我有过滤 SQL,它返回列数不确定的查询,并且希望在存储过程中使用结果。
DECLARE @RecordSelectionSql VARCHAR(MAX)
SET @RecordSelectionSql = (SELECT SQLQUERY FROM RecordSelection WHERE Id = @Id) + ' AND ([Active] = 1)'
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += ',' + CHAR(13) + CHAR(10) + CHAR(9) + name + ' ' + system_type_name
FROM sys.dm_exec_describe_first_result_set(@RecordSelectionSql, NULL, 0);
SELECT @sql = N'CREATE TABLE #TmpImport
(' + STUFF(@sql, 1, 1, N'') + '
);';
EXEC (@sql)
INSERT INTO #TmpImport
EXEC (@RecordSelectionSql)
但是我收到错误
Invalid object name '#TmpImport'.
如何正确编码这部分?
编辑:在 RecordSelection 上添加缺失条件
编辑2: 我无法使用下面的代码,因为 #TmpImport 在 @RecordSelectionSql 执行后被破坏。
DECLARE @RecordSelectionSql AS VARCHAR(MAX)
SET @RecordSelectionSql = 'SELECT X.* INTO #TmpImport FROM ('
+ (SELECT SQLQUERY FROM RecordSelection WHERE Id = @Id) + ' AND ([Active] = 1) AS X'
EXEC (@RecordSelectionSql)
SELECT * FROM #TmpImport
给出同样的错误
Invalid object name '#TmpImport'.
最佳答案
临时表仅在创建它们的 session 中可用。对于动态 SQL,这意味着它在动态 SQL 运行后不可用。您的选择是:
- 创建一个全局临时表,该表将在 session 外持续存在,直到使用双哈希以另一种方式从 TempDB 中显式删除或清除该表:
create table ##GlobalTemp
--要合并下面 Radu 的非常相关的评论:因为此表在您的 session 之外持续存在,所以您需要确保不会创建其中两个表或有两个不同的进程尝试处理其中的数据。您需要有一种方法来唯一标识您想要处理的全局临时表。 - 您可以创建一个常规表,然后记得再次删除它。
- 在动态 SQL 脚本中包含需要引用临时表的任何逻辑
对于您的特定实例,您最好只需执行 select into
,它将根据所选数据生成表结构。
关于sql-server - 如何从生成的sql返回本地临时表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40721155/