sql-server - 如何从生成的sql返回本地临时表

标签 sql-server tsql stored-procedures

我有过滤 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 运行后不可用。您的选择是:

  1. 创建一个全局临时表,该表将在 session 外持续存在,直到使用双哈希以另一种方式从 TempDB 中显式删除或清除该表:create table ##GlobalTemp
    --要合并下面 Radu 的非常相关的评论:因为此表在您的 session 之外持续存在,所以您需要确保不会创建其中两个表或有两个不同的进程尝试处理其中的数据。您需要有一种方法来唯一标识您想要处理的全局临时表。
  2. 您可以创建一个常规表,然后记得再次删除它。
  3. 在动态 SQL 脚本中包含需要引用临时表的任何逻辑

对于您的特定实例,您最好只需执行 select into ,它将根据所选数据生成表结构。

关于sql-server - 如何从生成的sql返回本地临时表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40721155/

相关文章:

mysql - 尝试在 Mysql 中创建存储过程时出现语法错误?

sql - IsNull() sql 函数

ASP.NET SQL Server 选择前 N 个值但跳过 M 个结果

c# - SqlDataAdapter 是否打开自己的连接?

sql - 如何重写此查询以不使用 union 子句

sql - 为什么 SQL Server 不能更改存储过程中的 View ?

c# - ASP.NET SQL 插入错误

sql-server - SQL Server 唯一 GUID

sql - 如何在 SQL 中检查 USER 是否已在数据库中创建?

mysql - 如何使用新的存储过程将列添加到工作表