it-swarm.com.de

Was ist der einfachste Weg, um eine temporäre Tabelle in SQL Server zu erstellen, die das Ergebnis einer gespeicherten Prozedur enthalten kann?

Oft muss ich beim Umgang mit SQL Server Folgendes schreiben.

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

insert into #table_name
execute some_stored_procedure;

Das Erstellen einer Tabelle mit der genauen Syntax als Ergebnis einer gespeicherten Prozedur ist jedoch eine mühsame Aufgabe. Zum Beispiel hat das Ergebnis von sp_helppublication 48 Spalten! Ich möchte wissen, ob es dafür einen einfachen Weg gibt.

Vielen Dank.

51
Just a learner

Wenn die Prozedur nur eine Ergebnismenge zurückgibt und die Option verteilte Ad-hoc-Abfragen aktiviert ist.

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

Oder Sie können einen Loopback-Verbindungsserver einrichten und diesen stattdessen verwenden.

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

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

In SQL Server 2012 und höher können Sie sys.dm_exec_describe_first_result_set lokal, vorausgesetzt, die gewünschte Ergebnismenge ist das erste Ergebnis:

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;

Ergebnis:

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

Beachten Sie, dass es eine Einschränkung gibt: Wenn Ihre gespeicherte Prozedur # temp-Tabellen erstellt, funktioniert die Metadatenfunktion nicht. Deshalb habe ich sp_who2 nicht verwendet. :-)

20
Aaron Bertrand

Nein. Das Ergebnis einer gespeicherten Prozedur kann sehr unterschiedlich sein: Es ist nicht so konzipiert, dass immer genau eine Ergebnismenge wie ein SELECT für ein Objekt zurückgegeben wird.

Sie müssen CREATE TABLE ausführen

2
gbn

Ich würde eine Prozedur schreiben, um die Tabelle für mich zu generieren:

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;

Dann nenne es mit:

EXEC p_create_table_from_procedure 'YOUR_TABLE_NAME_HERE', 'YOUR_PROCEDURE_NAME_HERE'

Hinweis: Ersetzen Sie 'YOUR_PROCEDURE_NAME_HERE' durch den Namen Ihrer eigenen gespeicherten Prozedur.

Hinweis: Ersetzen Sie YOUR_TABLE_NAME_HERE durch den Tabellennamen Ihrer Wahl.

Das Obige wird ungefähr so ​​etwas erzeugen:

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
    );
0
WonderWorker