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

时间:2016-11-21 13:18:20

标签: 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上添加缺失条件

EDIT2: 我无法使用下面的代码,因为#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'.

2 个答案:

答案 0 :(得分:5)

临时表仅在创建它们的会话中可用。使用Dynamic SQL,这意味着在运行Dynamic SQL后它不可用。您的选择是:

  1. 创建一个全局临时表,它将在会话之外保留,直到以另一种方式显式删除或清除TempDB,使用双哈希:create table ##GlobalTemp
    - 要在下面加入Radu非常相关的注释:由于此表在会话之外仍然存在,因此您需要确保不创建其中两个或有两个不同的进程尝试处理其中的数据。您需要有一种方法来唯一标识要处理的全局临时表。
  2. 您可以创建一个常规表,然后记得再次删除它。
  3. 包括在动态SQL脚本中引用临时表所需的任何逻辑
  4. 对于您的特定实例,您最好只执行一个select into,它将根据所选数据生成您的表结构。

答案 1 :(得分:1)

选择临时表会容易得多。

例如

SELECT * INTO #TmpImport FROM SomeTable