sql-server - 从函数或存储过程返回动态 SQL 表以在查询中使用
问题描述
我有许多表具有类型为 DATETIME 的“已删除”字段,我使用该字段将记录标记为已删除(而不是完全删除它们)。
我经常发现自己从这些表中请求数据并希望排除已删除的记录。我现在正在做的事情是这样的:
SELECT A.*
FROM (SELECT * FROM [TargetTable] WHERE (Deleted IS NULL)) AS A
WHERE (.........)
是否有可能有一个存储过程/函数,我可以将表名传递给它并返回过滤后的表?就像是:
SELECT A.*
FROM fnExcludeDeleted('MyTable') AS A
WHERE (.........)
我尝试使用表值函数来执行此操作,但据我所知,我需要定义结果表的列。我不能这样做,因为它并不总是我使用该函数的同一张表。
解决方案
在我看来,你不能用表值函数来做到这一点,因为它们需要静态表声明。不幸的是,您的表声明不一样。因此,您无法借助表值函数来实现这一点。在以下存储过程中,可能有助于解决您的问题。
这个存储过程基于以下步骤;
- 生成声明的表脚本
- 创建一个全局临时文件,它与声明的表具有相同的结构
- 将原始表数据填充到临时表中
- 返回临时表的结果集
注意:此查询使用GetTableCreateScript存储过程来获取声明的表创建脚本。
已编辑:为 SQL Server 2017STRING_AGG
的较低版本删除并添加了以组合行。XML PATH
DROP TABLE IF EXISTS TargetTable1
GO
CREATE TABLE TargetTable1 (Col1 INT , Deleted DATE)
GO
---Populating test data---
INSERT INTO TargetTable1 VALUES (1,GETDATE())
INSERT INTO TargetTable1 VALUES (2,NULL)
INSERT INTO TargetTable1 VALUES (3,GETDATE())
INSERT INTO TargetTable1 VALUES (4,NULL)
GO
CREATE OR ALTER PROC DynamicSQL
@TableName AS VARCHAR(200)
AS
DROP TABLE IF EXISTS ##TempDynamic
DECLARE @SQLDynamicTable AS VARCHAR(MAX)
DECLARE @SQLDynamicRows AS VARCHAR(MAX)
CREATE TABLE #DynamicSQL (S VARCHAR(MAX))
INSERT INTO #DynamicSQL
EXEC [dbo].GetTableCreateScript @TableName --->Generate Table Definition
---You can find GetTableCreateScript create script https://www.c-sharpcorner.com/blogs/generate-table-defination-in-sql-server-without-gui
--SELECT @SQLDynamicTable=REPLACE(STRING_AGG(S,' '),@TableName, '##TempDynamic') FROM #DynamicSQL ----->Create TempTable for SQL Server 2017 and upper version
SELECT @SQLDynamicTable=STUFF((
SELECT ' ' + s
FROM #DynamicSQL
FOR XML PATH('')
), 1, 1, '')
SET @SQLDynamicTable = REPLACE(@SQLDynamicTable,@TableName, '##TempDynamic')
PRINT @SQLDynamicTable
EXEC (@SQLDynamicTable)
SET @SQLDynamicRows = 'INSERT INTO ##TempDynamic SELECT * FROM ' + @TableName
EXEC(@SQLDynamicRows)
SELECT * FROM ##TempDynamic
WHERE Deleted IS NULL
GO
EXEC DynamicSQL 'TargetTable1'
+------+---------+
| Col1 | Deleted |
+------+---------+
| 2 | NULL |
| 4 | NULL |
+------+---------+
推荐阅读
- html - 由于未知原因,圆锥梯度 css 在 React 中不起作用
- mysql - MySQL 左/右/外连接
- python - 使用 Django 的 ORM 聚合 OneToMany 关系中不同日期的数量
- javascript - mongodb函数currentOp()的返回记录在哪里?
- sql - 如何将选择查询的结果放入 postgresql 中的函数
- php - 打开引导模式后,我的 php 变量被重置
- c++ - 如何基于循环迭代器选择函数
- android - Android 导航组件重新创建底部导航片段
- reactjs - 状态中的属性在动作创建者中变得未定义
- r - 对具有重复的组进行方差分析