在SQL存储过程中将dynamicSQL结果转换为临时表

代码如下:

ALTER PROCEDURE dbo.pdpd_DynamicCall @SQLString varchar(4096) = null AS Begin create TABLE #T1 ( column_1 varchar(10) , column_2 varchar(100) ) insert into #T1 execute ('execute ' + @SQLString ) select * from #T1 End 

问题是,我想调用不同的过程,可以给不同的列。 因此,我将不得不一般定义表#T1。 但我不知道如何。

任何人都可以帮我解决这个问题吗?

尝试:

 SELECT into #T1 execute ('execute ' + @SQLString ) 

而且这种味道真的很糟糕,就像一个SQL注入漏洞。


更正 (per @ CarpeDiem的评论):

 INSERT into #T1 execute ('execute ' + @SQLString ) 

另外,如果sqlstring不是过程,则省略'execute'

您可以dynamic地定义表格,就像您dynamic插入表格一样,但问题在于临时表格的范围。 例如,这个代码:

 DECLARE @sql varchar(max) SET @sql = 'CREATE TABLE #T1 (Col1 varchar(20))' EXEC(@sql) INSERT INTO #T1 (Col1) VALUES ('This will not work.') SELECT * FROM #T1 

将返回错误“无效的对象名称#T1”。 这是因为临时表#T1是在比执行代码块更“低一级”的地方创build的。 为了解决,请使用全局临时表:

 DECLARE @sql varchar(max) SET @sql = 'CREATE TABLE ##T1 (Col1 varchar(20))' EXEC(@sql) INSERT INTO ##T1 (Col1) VALUES ('This will work.') SELECT * FROM ##T1 

希望这有助于Jesse

要小心全局临时表解决scheme,因为如果两个用户同时使用相同的例程,则全局临时表可以被所有用户看到,因此这可能会失败。

在名称中dynamic创build一个全局临时表。 然后你可以通过dyn sql在你的代码中使用它,而不用担心调用同一个sproc的另一个进程会使用它。 如果每次运行时都不知道底层选定表所期待的内容,那么这是非常有用的,因此您无法事先明确创build临时表。 即 – 你需要使用SELECT * INTO语法

 DECLARE @TmpGlobalTable varchar(255) = 'SomeText_' + convert(varchar(36),NEWID()) -- select @TmpGlobalTable -- build query SET @Sql = 'SELECT * INTO [##' + @TmpGlobalTable + '] FROM SomeTable' EXEC (@Sql) EXEC ('SELECT * FROM [##' + @TmpGlobalTable + '] ') EXEC ('DROP TABLE [##' + @TmpGlobalTable + ']') PRINT 'Dropped Table ' + @TmpGlobalTable 
 INSERT INTO #TempTable EXEC(@SelectStatement) 

不知道我是否理解,但也许你可以在一个string中形成CREATE语句,然后执行该string? 这样你可以添加任意数量的列。

 DECLARE @EmpGroup INT =3 , @IsActive BIT=1 DECLARE @tblEmpMaster AS TABLE (EmpCode VARCHAR(20),EmpName VARCHAR(50),EmpAddress VARCHAR(500)) INSERT INTO @tblEmpMaster EXECUTE SPGetEmpList @EmpGroup,@IsActive SELECT * FROM @tblEmpMaster 
 CREATE PROCEDURE dbo.pdpd_DynamicCall AS DECLARE @SQLString_2 NVARCHAR(4000) SET NOCOUNT ON Begin --- Create global temp table CREATE TABLE ##T1 ( column_1 varchar(10) , column_2 varchar(100) ) SELECT @SQLString_2 = 'INSERT INTO ##T1( column_1, column_2) SELECT column_1 = "123", column_2 = "MUHAMMAD IMRON"' SELECT @SQLString_2 = REPLACE(@SQLString_2, '"', '''') EXEC SP_EXECUTESQL @SQLString_2 --- Test Display records SELECT * FROM ##T1 --- Drop global temp table IF OBJECT_ID('tempdb..##T1','u') IS NOT NULL DROP TABLE ##T1 End