web-dev-qa-db-ja.com

SQLストアドプロシージャの一時テーブルへの動的SQLの結果

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

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

誰もこの問題で私を助けることができますか?

43
Dhana

試してください:

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

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


修正(@CarpeDiemのコメントごと):

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

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

37
Joel Coehoorn

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

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

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

31
Jesse

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

16
Runonthespot

名前にGUID=を動的に使用してグローバル一時テーブルを作成します。その後、同じsprocを呼び出す別のプロセスが使用することを心配せずに、dyn sqlを介してコードで作業できます。事前に明示的に一時テーブルを作成することができないように、基礎となる選択されたテーブルが実行されるたびに何を期待するのかわからない場合に役立ちます。

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 
10
paul
INSERT INTO #TempTable
EXEC(@SelectStatement)
7
MTS

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

0
Seb
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
0
URVISH SUTHAR
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
0
Muhammad Imron