it-swarm.asia

Apa cara termudah untuk membuat tabel temporer di SQL Server yang dapat menampung hasil dari prosedur yang tersimpan?

Banyak kali saya perlu menulis sesuatu seperti berikut ketika berhadapan dengan SQL Server.

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

insert into #table_name
execute some_stored_procedure;

Tetapi membuat tabel yang memiliki sintaks yang tepat karena hasil dari prosedur tersimpan adalah tugas yang membosankan. Misalnya, hasil sp_helppublication memiliki 48 kolom! Saya ingin tahu apakah ada cara mudah untuk melakukan ini.

Terima kasih.

51
Just a learner

Jika prosedur hanya mengembalikan satu set hasil dan opsi kueri yang didistribusikan ad hoc diaktifkan.

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

Atau Anda dapat mengatur server yang ditautkan loopback dan menggunakannya.

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

Di SQL Server 2012 dan di atasnya, Anda dapat menggunakan sys.dm_exec_describe_first_result_set secara lokal, dengan asumsi hasil yang Anda inginkan adalah hasil pertama :

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;

Hasil:

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

Perhatikan ada batasan: jika prosedur tersimpan Anda membuat tabel #temp, fungsi metadata tidak berfungsi. Ini sebabnya saya tidak menggunakan sp_who2. :-)

20
Aaron Bertrand

Tidak. Hasil dari prosedur yang disimpan dapat sangat bervariasi: itu tidak dirancang untuk selalu mengembalikan tepat satu hasil yang ditetapkan seperti SELECT pada beberapa objek.

Anda harus menjalankan CREATE TABLE

2
gbn

Saya akan menulis prosedur untuk menghasilkan tabel untuk saya:

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;

Kemudian sebut dengan:

EXEC p_create_table_from_procedure 'YOUR_TABLE_NAME_HERE', 'YOUR_PROCEDURE_NAME_HERE'

Catatan: Ganti 'YOUR_PROCEDURE_NAME_HERE' dengan nama prosedur tersimpan Anda sendiri.

Catatan: Ganti YOUR_TABLE_NAME_HERE dengan nama tabel pilihan Anda.

Di atas akan menghasilkan sesuatu seperti ini:

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