50

コードは次のとおりです。

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を一般的に定義する必要があります。しかし、私は方法がわかりません。

誰かがこの問題について私を助けることができますか?

4

9 に答える 9

45

試す:

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

そして、これはSQLインジェクションの脆弱性のように本当に悪いにおいがします.


修正(@CarpeDiemのコメントによる):

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

'execute'また、 SQL文字列がプロシージャ以外の場合は省略します

于 2009-03-19T12:56:56.117 に答える
36

テーブルを動的に挿入するのと同じように動的に定義できますが、問題は一時テーブルのスコープにあります。たとえば、次のコードは次のとおりです。

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が、実行中のコードのブロックよりも「低いレベル」で作成されるためです。修正するには、グローバル一時テーブルを使用します。

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

これがお役に立てば幸い、ジェシー

于 2009-06-16T18:50:33.577 に答える
22

2 人のユーザーが同じルーチンを同時に使用すると失敗する可能性があるため、グローバル一時テーブル ソリューションには注意してください。グローバル一時テーブルはすべてのユーザーに表示されます...

于 2010-11-15T16:03:48.887 に答える
11

名前に GUID を含むグローバル一時テーブルを動的に作成します。次に、同じ sproc を呼び出す別のプロセスがそれを使用することを心配することなく、dyn sql を介してコード内で作業できます。これは、基礎となる選択されたテーブルを実行するたびに何が期待できるかわからないため、事前に一時テーブルを明示的に作成できない場合に役立ちます。つまり、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 
于 2013-03-15T17:26:54.270 に答える
8
INSERT INTO #TempTable
EXEC(@SelectStatement)
于 2011-06-14T22:29:39.563 に答える
0
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
于 2012-03-31T11:01:03.480 に答える
0

T-SQLを使用してストアドプロシージャ出力から一時テーブルを動的に作成するための以下のコードを試してください

declare @ExecutionName varchar(1000) = 'exec [spname] param1,param2 '
declare @sqlStr varchar(max) = ''

   declare @tempTableDef nvarchar(max) =   
  (  
  SELECT distinct   
   STUFF(  
    (  
     SELECT ','+a.[name]+' '+[system_type_name]  
  +'  
   ' AS [text()]  
     FROM sys.dm_exec_describe_first_result_set  (@ExecutionName, null, 0) a  
     ORDER BY a.column_ordinal  
     FOR XML PATH ('')  
    ), 1, 1, '') tempTableDef   

  FROM sys.dm_exec_describe_first_result_set  (@ExecutionName, null, 0) b  
  )  

  IF ISNULL(@tempTableDef ,'') = '' RAISERROR( 'Invalid SP Configuration. At least one column is required in Select list of SP output.',16,1) ;    
                                      
  set @tempTableDef='CREATE TABLE #ResultDef   
  (  
  ' + REPLACE(@tempTableDef,'
','') +'  
  )  

  INSERT INTO #ResultDef   
  ' + @ExecutionName    
          
  Select  @sqlStr  = @tempTableDef +' Select * from  #ResultDef '   
exec(@sqlStr)
于 2021-03-18T11:03:29.677 に答える
-1

よく理解しているかどうかはわかりませんが、文字列内にCREATEステートメントを作成して、その文字列を実行できますか?そうすれば、必要な数の列を追加できます。

于 2009-03-19T12:40:16.080 に答える