Вставьте результаты хранимой процедуры во временную таблицу - PullRequest
1468 голосов
/ 17 марта 2009

Как мне сделать SELECT * INTO [temp table] FROM [stored procedure]? Не FROM [Table] и без определения [temp table]?

Select все данные из BusinessLine в tmpBusLine работают нормально.

select *
into tmpBusLine
from BusinessLine

Я пытаюсь сделать то же самое, но использование stored procedure, которое возвращает данные, не совсем то же самое.

select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'

Выходное сообщение:

Сообщение 156, Уровень 15, Состояние 1, Строка 2 Неверный синтаксис рядом с ключевым словом 'Exec'.

Я прочитал несколько примеров создания временной таблицы с той же структурой, что и для хранимой процедуры вывода, которая работает нормально, но было бы неплохо не указывать столбцы.

Ответы [ 27 ]

8 голосов
/ 11 августа 2009

Другой метод заключается в создании типа и использовании PIPELINED для последующей передачи вашего объекта. Это ограничено знанием колонок как бы то ни было. Но у него есть преимущество:

SELECT * 
FROM TABLE(CAST(f$my_functions('8028767') AS my_tab_type))
3 голосов
/ 24 марта 2015

Если вам известны передаваемые параметры и если у вас нет доступа к программе sp_configure, то отредактируйте хранимую процедуру с этими параметрами, и ее можно сохранить в глобальной таблице ##.

2 голосов
/ 27 апреля 2019

Это простой двухэтапный процесс: - создать временную таблицу - Вставить во временную таблицу.

Код для выполнения того же:

CREATE TABLE #tempTable (Column1 int, Column2 varchar(max));
INSERT INTO #tempTable 
EXEC [app].[Sproc_name]
@param1 = 1,
@param2 =2;
1 голос
/ 13 июня 2019

После поиска я нашел способ динамически создать временную таблицу для любой хранимой процедуры, не используя OPENROWSET или OPENQUERY, используя общую схему определения результата хранимой процедуры, особенно если вы не являетесь администратором базы данных.

Сервер Sql имеет встроенную процедуру sp_describe_first_result_set, которая может предоставить вам схему любого набора результатов процедур. Я создал таблицу схемы из результатов этой процедуры и вручную установил все поля в NULLABLE.

declare @procname varchar(100) = 'PROCEDURENAME' -- your procedure name
declare @param varchar(max) = '''2019-06-06''' -- your parameters 
declare @execstr nvarchar(max) = N'exec ' + @procname
declare @qry nvarchar(max)

-- Schema table to store the result from sp_describe_first_result_set.
create table #d
(is_hidden  bit  NULL, column_ordinal   int  NULL, name sysname NULL, is_nullable   bit  NULL, system_type_id   int  NULL, system_type_name nvarchar(256) NULL,
max_length  smallint  NULL, precision   tinyint  NULL,  scale   tinyint  NULL,  collation_name  sysname NULL, user_type_id  int NULL, user_type_database    sysname NULL,
user_type_schema    sysname NULL,user_type_name sysname NULL,assembly_qualified_type_name   nvarchar(4000),xml_collection_id    int NULL,xml_collection_database    sysname NULL,
xml_collection_schema   sysname NULL,xml_collection_name    sysname NULL,is_xml_document    bit  NULL,is_case_sensitive bit  NULL,is_fixed_length_clr_type  bit  NULL,
source_server   sysname NULL,source_database    sysname NULL,source_schema  sysname NULL,source_table   sysname NULL,source_column  sysname NULL,is_identity_column bit NULL,
is_part_of_unique_key   bit NULL,is_updateable  bit NULL,is_computed_column bit NULL,is_sparse_column_set   bit NULL,ordinal_in_order_by_list   smallint NULL,
order_by_list_length    smallint NULL,order_by_is_descending    smallint NULL,tds_type_id   int  NULL,tds_length    int  NULL,tds_collation_id  int NULL,
tds_collation_sort_id   tinyint NULL)


-- Get result set definition of your procedure
insert into #d
EXEC sp_describe_first_result_set @exestr, NULL, 0

-- Create a query to generate and populate a global temp table from above results
select 
@qry = 'Create table ##t(' +
stuff(  
    (select ',' + name + ' '+ system_type_name + ' NULL'
    from #d d For XML Path, TYPE)
    .value(N'.[1]', N'nvarchar(max)')
, 1,1,'')
+ ')

insert into ##t 
Exec '+@procname+' ' + @param

Exec sp_executesql @qry

-- Use below global temp table to query the data as you may
select * from ##t

-- **WARNING** Don't forget to drop the global temp table ##t.
--drop table ##t
drop table #d 

Разработано и протестировано на версии Sql Server - Microsoft SQL Server 2016 (окончательная первоначальная версия) - 13.0.1601.5 (сборка 17134 :)

Вы можете настроить схему для используемой версии сервера SQL (при необходимости).

0 голосов
/ 10 июля 2018

Что ж, вам нужно создать временную таблицу, но у нее не должно быть правильной схемы .... Я создал хранимую процедуру, которая изменяет существующую временную таблицу, чтобы она имела необходимые столбцы с правильный тип данных и порядок (удаление всех существующих столбцов, добавление новых столбцов):

GO
create procedure #TempTableForSP(@tableId int, @procedureId int)  
as   
begin  
    declare @tableName varchar(max) =  (select name  
                                        from tempdb.sys.tables 
                                        where object_id = @tableId
                                        );    
    declare @tsql nvarchar(max);    
    declare @tempId nvarchar(max) = newid();      
    set @tsql = '    
    declare @drop nvarchar(max) = (select  ''alter table tempdb.dbo.' + @tableName 
            +  ' drop column ''  + quotename(c.name) + '';''+ char(10)  
                                   from tempdb.sys.columns c   
                                   where c.object_id =  ' + 
                                         cast(@tableId as varchar(max)) + '  
                                   for xml path('''')  
                                  )    
    alter table tempdb.dbo.' + @tableName + ' add ' + QUOTENAME(@tempId) + ' int;
    exec sp_executeSQL @drop;    
    declare @add nvarchar(max) = (    
                                select ''alter table ' + @tableName 
                                      + ' add '' + name 
                                      + '' '' + system_type_name 
                           + case when d.is_nullable=1 then '' null '' else '''' end 
                                      + char(10)   
                              from sys.dm_exec_describe_first_result_set_for_object(' 
                               + cast(@procedureId as varchar(max)) + ', 0) d  
                                order by column_ordinal  
                                for xml path(''''))    

    execute sp_executeSQL  @add;    
    alter table '  + @tableName + ' drop column ' + quotename(@tempId) + '  ';      
    execute sp_executeSQL @tsql;  
end         
GO

create table #exampleTable (pk int);

declare @tableId int = object_Id('tempdb..#exampleTable')
declare @procedureId int = object_id('examplestoredProcedure')

exec #TempTableForSP @tableId, @procedureId;

insert into #exampleTable
exec examplestoredProcedure

Примечание это не будет работать, если sys.dm_exec_describe_first_result_set_for_object не может определить результаты хранимой процедуры (например, если она использует временную таблицу).

0 голосов
/ 27 января 2017

Это можно сделать в SQL Server 2014+, если SP возвращает только одну таблицу. Если кто-нибудь найдет способ сделать это для нескольких столов, я бы хотел узнать об этом.

DECLARE @storeProcname NVARCHAR(MAX) = ''

SET @storeProcname = 'myStoredProc'

DECLARE @strSQL AS VARCHAR(MAX) = 'CREATE TABLE myTableName '

SELECT @strSQL = @strSQL+STUFF((
SELECT ',' +name+' ' + system_type_name 
FROM sys.dm_exec_describe_first_result_set_for_object (OBJECT_ID(@storeProcname),0)
FOR XML PATH('')
),1,1,'(') + ')'

EXEC (@strSQL)

INSERT INTO myTableName
EXEC ('myStoredProc @param1=1, @param2=2')

SELECT * FROM myTableName

DROP TABLE myTableName

Это извлекает определение возвращаемой таблицы из системных таблиц и использует его для создания временной таблицы для вас. Затем вы можете заполнить его из SP, как указано выше.

Существуют также варианты этого, которые также работают с динамическим SQL.

0 голосов
/ 19 августа 2014

Я бы сделал следующее

  1. Создание (преобразование SP) в UDF (значение таблицы UDF).

  2. select * into #tmpBusLine from dbo.UDF_getBusinessLineHistory '16 Mar 2009'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...