it-swarm.asia

ما هي أسهل طريقة لإنشاء جدول مؤقت في SQL Server يمكنه الاحتفاظ بنتيجة إجراء مخزن؟

في كثير من الأحيان أحتاج إلى كتابة شيء مثل ما يلي عند التعامل مع SQL Server.

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

insert into #table_name
execute some_stored_procedure;

لكن إنشاء جدول يحتوي على بناء جملة دقيق نتيجة لإجراء مخزن هو مهمة شاقة. على سبيل المثال ، نتيجة sp_helppublication لها 48 عمودًا! أريد أن أعرف ما إذا كانت هناك طريقة سهلة للقيام بذلك.

شكر.

51
Just a learner

إذا قام الإجراء فقط بإرجاع مجموعة نتائج واحدة وتم تمكين الخيار الاستعلامات الموزعة المخصصة .

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')
38
Martin Smith

في 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. :-)

20
Aaron Bertrand

لا. يمكن أن تختلف نتيجة الإجراء المخزن بشكل كبير: فهي ليست مصممة لإرجاع مجموعة نتائج واحدة بالضبط مثل SELECT على كائن ما.

عليك عليك تنفيذ إنشاء جدول

2
gbn

سأكتب إجراءً لإنشاء الجدول لي:

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