SQL Server에서 저장 프로 시저의 결과를 보유 할 수있는 임시 테이블을 만드는 가장 쉬운 방법은 무엇입니까?


50

여러 번 SQL Server를 처리 할 때 다음과 같은 내용을 작성해야합니다.

create table #table_name
(
    column1 int,
    column2 varchar(200)
    ...
)

insert into #table_name
execute some_stored_procedure;

그러나 저장 프로 시저의 결과는 지루한 작업이므로 정확한 구문을 가진 테이블을 만듭니다. 예를 들어 sp_helppublication 의 결과 에는 48 개의 열이 있습니다! 이 작업을 수행하는 쉬운 방법이 있는지 알고 싶습니다.

감사.


정의 된 출력 형식을 원하거나 DBA 인 경우 정의 된 형식을 선호해야합니다. 테이블 값 UDF를 고려하십시오. 불행히도 그들은 몇 가지 심각한 제한 사항이 있으므로 항상 옵션은 아닙니다.
모든 거래의 존

답변:


36

프로 시저가 하나의 결과 세트 만 리턴하고 임시 분산 조회 옵션이 사용 가능한 경우.

SELECT * 
INTO #T 
FROM OPENROWSET('SQLNCLI', 
                'Server=(local)\MSSQL2008;Trusted_Connection=yes;',
                 'SET FMTONLY OFF;EXEC sp_who')

또는 루프백 연결된 서버를 설정하고 대신 사용할 수 있습니다.

EXEC sp_addlinkedserver @server = 'LOCALSERVER',  @srvproduct = '',
                        @provider = 'SQLNCLI', @datasrc = @@servername

SELECT *
INTO  #T
FROM OPENQUERY(LOCALSERVER, 
               'SET FMTONLY OFF;
               EXEC sp_who')

당신은 의미하지 SET FMT_ONLY ON않습니까?
Andreas Ågren

@Andreas-아니요 아이디어는 저장 프로 시저 출력에서 ​​테이블을 만들고 채우는 것으로 가정했기 때문에 아니요.
Martin Smith

18

SQL Server 2012 이상에서는 sys.dm_exec_describe_first_result_set이후 결과 집합이 첫 번째 결과 라고 가정하고 로컬에서 사용할 수 있습니다.

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('sp_who', NULL, 1);

SELECT @sql = N'CREATE TABLE #f
(' + STUFF(@sql, 1, 1, N'') + '
);';

PRINT @sql;

결과:

CREATE TABLE #f
(
    spid smallint,
    ecid smallint,
    status nchar(30),
    loginame nvarchar(128),
    hostname nchar(128),
    blk char(5),
    dbname nvarchar(128),
    cmd nchar(16),
    request_id int
);

저장 프로 시저가 #temp 테이블을 만드는 경우 메타 데이터 기능이 작동하지 않습니다. 이것이 sp_who2를 사용하지 않은 이유입니다. :-)


는 IS SELECT @sql += *expression*구문 어딘가에 문서화? ORDER BY안정시키기 위해 포함 되어야 하는가?
Ross Presser

1
@Ross는 SQL Server 2008에 도입되었으며 여기 에 문서화되어 있습니다 . ORDER BY실제로 이것을 안정적 으로 만드는 것으로 알려져 있습니다. 결과를 예측 가능한 순서로하려면 FOR XML PATH또는 충분한 새 버전의 SQL Server 인 경우을 사용하십시오 STRING_AGG.
Aaron Bertrand

1
약간의 수정 : 당신이 연산에 연결 +=... 문자열이 +=설명되어 있습니다 여기에 . 그러나 감사합니다!
Ross Presser

@ 로스 p, 죄송합니다.
Aaron Bertrand

3

아니요. 저장 프로 시저의 결과는 매우 다양 할 수 있습니다. 일부 개체의 SELECT와 같이 정확히 하나의 결과 집합을 반환하도록 설계되지 않았습니다.

당신은 해야 CREATE TABLE을 실행


1

나를 위해 테이블을 생성하는 절차를 작성합니다.

CREATE PROCEDURE [dbo].[p_create_table_from_procedure]
    @TABLE_NAME AS NVARCHAR(MAX),
    @PROCEDURE_NAME AS NVARCHAR(MAX)

As
    DECLARE @CREATE_TABLE_QUERY NVARCHAR(MAX) = N'';


    SELECT 
        @CREATE_TABLE_QUERY += ', ' + name + ' ' + UPPER(system_type_name) + CHAR(13) + CHAR(10) + CHAR(9)

    FROM 
        sys.dm_exec_describe_first_result_set(@procedure_name, NULL, 1);


    SELECT 
        @CREATE_TABLE_QUERY = N'CREATE TABLE ' + @table_name + '(' + CHAR(13) + CHAR(10) + CHAR(9) + STUFF(@CREATE_TABLE_QUERY, 1, 1, N'') + ');';

    PRINT @CREATE_TABLE_QUERY;

그런 다음 전화하십시오.

EXEC p_create_table_from_procedure 'YOUR_TABLE_NAME_HERE', 'YOUR_PROCEDURE_NAME_HERE'

참고 : 'YOUR_PROCEDURE_NAME_HERE'를 자체 저장 프로 시저 이름으로 바꾸십시오.

참고 : YOUR_TABLE_NAME_HERE를 선택한 테이블 이름으로 바꾸십시오.

위의 내용은 다음과 같습니다.

CREATE TABLE YOUR_TABLE_NAME_HERE(
     WeekName VARCHAR(40)
    , Line Name VARCHAR(50)
    , TheDate DATETIME
    , ReceivedAll INT
    , Answered INT
    , Abandoned INT
    , Call Length INT
    , WaitTimeAnswer INT
    , WaitTimeAbandon INT
    , PeriodName VARCHAR(10)
    , Week SMALLINT
    , Period SMALLINT
    , Year SMALLINT
    , WeekInPeriod SMALLINT
    , NumWeeksInPeriod SMALLINT
    , WeekendDate DATETIME
    , CRCOperative VARCHAR(100)
    , CallType VARCHAR(20)
    , Charge Time INT
    , SourceNumber VARCHAR(80)
    , DestinationNumber VARCHAR(80)
    , CallStart DATETIME
    , Out of Hours VARCHAR(12)
    , IsWorkingDay BIT
    );

위의 @AaronBertrand의 답변과 다른 점은 무엇입니까?
Max Vernon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.