programing

동적 SQL 결과를 SQL 저장 프로시저의 임시 테이블로 변환

testmans 2023. 8. 28. 20:54
반응형

동적 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 테이블을 일반적으로 정의해야 합니다.하지만 나는 방법은 잘 모르겠습니다.

누가 이 문제를 도와줄 수 있습니까?

시도:

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

그리고 이것은 sql 주입 취약성처럼 정말 나쁜 냄새가 납니다.


수정(@CarpeDiem의 코멘트에 따름):

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

또한, 생략'execute'sql 문자열이 프로시저가 아닌 경우

동적으로 테이블에 삽입하는 것처럼 테이블을 동적으로 정의할 수 있지만 문제는 임시 테이블의 범위에 있습니다.예를 들어, 이 코드는 다음과 같습니다.

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

이게 도움이 되길 바라, 제시

글로벌 템플릿 솔루션에 주의하십시오. 두 사용자가 동시에 동일한 루틴을 사용할 경우 모든 사용자가 글로벌 템플릿을 볼 수 있으므로 실패할 수 있습니다.

이름에 GUID가 있는 글로벌 임시 테이블을 동적으로 생성합니다.그러면 동일한 저장 프로시저를 호출하는 다른 프로세스가 사용할 걱정 없이 dynsql을 통해 코드에서 작업할 수 있습니다.이 기능은 기본 선택 테이블이 실행될 때마다 무엇을 기대해야 할지 몰라서 미리 명시적으로 임시 테이블을 만들 수 없는 경우에 유용합니다.i - 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)

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)
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

제가 잘 이해했는지는 모르겠지만, 문자열 안에 CREATE 문을 만든 다음 해당 문자열을 실행할 수 있을까요?그러면 원하는 만큼 열을 추가할 수 있습니다.

언급URL : https://stackoverflow.com/questions/662049/dynamic-sql-results-into-temp-table-in-sql-stored-procedure

반응형