Вставка результатов хранимой процедуры во временную таблицу

Как мне сделать 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'
 

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

Msg 156, уровень 15, состояние 1, строка 2 Некорректный синтаксис рядом с ключевым словом «exec».

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

вопрос задан 17.03.2009
Ferdeen
8002 репутация

25 ответов


  • 627 рейтинг

    Для этого вы можете использовать OPENROWSET . Взгляни. Я также включил код sp_configure для включения специальных распределенных запросов, если он еще не включен.

     CREATE PROC getBusinessLineHistory
    AS
    BEGIN
        SELECT * FROM sys.databases
    END
    GO
    
    sp_configure 'Show Advanced Options', 1
    GO
    RECONFIGURE
    GO
    sp_configure 'Ad Hoc Distributed Queries', 1
    GO
    RECONFIGURE
    GO
    
    SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
         'EXEC getBusinessLineHistory')
    
    SELECT * FROM #MyTempTable
     
    ответ дан Aaron Alton, с репутацией 17736, 4.08.2009
  • 524 рейтинг

    Если вы хотите сделать это без предварительного объявления временной таблицы, вы можете попытаться создать определенную пользователем функцию, а не хранимую процедуру, и сделать эту пользовательскую функцию возвращенной таблицей. Альтернативно, если вы хотите использовать хранимую процедуру, попробуйте что-то вроде этого:

     CREATE TABLE #tmpBus
    (
       COL1 INT,
       COL2 INT
    )
    
    INSERT INTO #tmpBus
    Exec SpGetRecords 'Params'
     
    ответ дан Gavin, с репутацией 10229, 17.03.2009
  • 268 рейтинг

    В SQL Server 2005 вы можете использовать INSERT INTO ... EXEC чтобы вставить результат хранимой процедуры в таблицу. Из документации MSDN INSERT (фактически, для SQL Server 2000):

     --INSERT...EXECUTE procedure example
    INSERT author_sales EXECUTE get_author_sales
     
    ответ дан Matt Hamilton, с репутацией 159536, 17.03.2009
  • 169 рейтинг

    Это ответ на слегка измененную версию вашего вопроса. Если вы можете отказаться от использования хранимой процедуры для пользовательской функции, вы можете использовать встроенную функцию, определяемую таблицей. Это, по сути, хранимая процедура (будет принимать параметры), которая возвращает таблицу в качестве результата; и поэтому будет удобно размещаться с инструкцией INTO.

    Вот хорошая статья о ней и другие пользовательские функции. Если у вас все еще есть потребность во время хранения хранимой процедуры, вы можете обернуть встроенную функцию, определенную пользователем, с помощью хранимой процедуры. Хранимая процедура просто передает параметры при вызове select * из встроенной функции, определяемой пользователем.

    Так, например, у вас будет встроенная пользовательская функция, ориентированная на таблицу, чтобы получить список клиентов для определенного региона:

     CREATE FUNCTION CustomersByRegion 
    (  
        @RegionID int  
    )
    RETURNS TABLE 
    AS
    RETURN 
      SELECT *
      FROM customers
      WHERE RegionID = @RegionID
    GO
     

    Затем вы можете вызвать эту функцию, чтобы получить то, что ваши результаты:

     SELECT * FROM CustomersbyRegion(1)
     

    Или сделать SELECT INTO:

     SELECT * INTO CustList FROM CustomersbyRegion(1)
     

    Если вам все еще нужна хранимая процедура, то заверните функцию как таковую:

     CREATE PROCEDURE uspCustomersByRegion 
    (  
        @regionID int  
    )
    AS
    BEGIN
         SELECT * FROM CustomersbyRegion(@regionID);
    END
    GO
     

    Я думаю, что это самый «безрадостный» метод для получения желаемых результатов. Он использует существующие функции, поскольку они предназначались для использования без дополнительных осложнений. Вложенная встроенная функция, определяемая пользователем, в хранимой процедуре, вы получаете доступ к функциям двумя способами. Плюс! У вас есть только одна точка обслуживания для фактического кода SQL.

    Было предложено использовать OPENROWSET, но это не то, для чего предназначалась функция OPENROWSET (из книги в Интернете):

    Включает всю информацию о подключении, которая требуется для доступа к удаленным данным из источника данных OLE DB. Этот метод является альтернативой доступу к таблицам на связанном сервере и является разовым, специальным методом подключения и доступа к удаленным данным с использованием OLE DB. Для более частых ссылок на источники данных OLE DB вместо этого используйте связанные серверы.

    Использование OPENROWSET выполнит эту работу, но при этом возникнут дополнительные накладные расходы для открытия локальных соединений и сортировки данных. Он также может быть не во всех случаях, поскольку для него требуется специальное разрешение запроса, которое создает угрозу безопасности и, следовательно, может быть нежелательным. Кроме того, подход OPENROWSET исключает использование хранимых процедур, возвращающих более одного набора результатов. Это может обеспечить объединение нескольких встроенных функций, определяемых пользователем, в одну хранимую процедуру.

    ответ дан Christian Loris, с репутацией 3665, 4.08.2009
  • 103 рейтинг
    EXEC sp_serveroption 'YOURSERVERNAME', 'DATA ACCESS', TRUE
    
    SELECT  *
    INTO    #tmpTable
    FROM    OPENQUERY(YOURSERVERNAME, 'EXEC db.schema.sproc 1')
    
    ответ дан Quassnoi, с репутацией 321748, 17.03.2009
  • 97 рейтинг

    Самое простое решение:

     CREATE TABLE #temp (...);
    
    INSERT INTO #temp
    EXEC [sproc];
     

    Если вы не знаете схему, вы можете сделать следующее. Обратите внимание, что в этом методе существуют серьезные риски безопасности.

     SELECT * 
    INTO #temp
    FROM OPENROWSET('SQLNCLI', 
                    'Server=localhost;Trusted_Connection=yes;', 
                    'EXEC [db].[schema].[sproc]')
     
    ответ дан Tigerjz32, с репутацией 2141, 13.03.2015
  • 82 рейтинг

    Когда хранимая процедура возвращает много столбцов, и вы не хотите вручную «создавать» временную таблицу для хранения результата, я нашел, что самый простой способ - войти в хранимую процедуру и добавить предложение «в» на последний оператор select и добавьте 1 = 0 в предложение where.

    Запустите хранимую процедуру один раз и вернитесь назад и удалите только что добавленный код SQL. Теперь у вас будет пустая таблица, соответствующая результату хранимой процедуры. Вы можете либо «создать таблицу как создать» для временной таблицы, либо просто вставить ее непосредственно в эту таблицу.

    ответ дан dotjoe, с репутацией 19658, 17.03.2009
  • 61 рейтинг
    declare @temp table
    (
        name varchar(255),
        field varchar(255),
        filename varchar(255),
        filegroup varchar(255),
        size varchar(255),
        maxsize varchar(255),
        growth varchar(255),
        usage varchar(255)
    );
    INSERT @temp  Exec sp_helpfile;
    select * from @temp;
    
    ответ дан nitin, с репутацией 659, 24.03.2011
  • 41 рейтинг

    Сохраняет ли ваша хранимая процедура только данные или их изменение? Если он используется только для извлечения, вы можете преобразовать хранимую процедуру в функцию и использовать общие выражения таблицы (CTE), не объявляя ее следующим образом:

     with temp as (
        select * from dbo.fnFunctionName(10, 20)
    )
    select col1, col2 from temp
     

    Однако все, что требуется получить от CTE, должно использоваться только в одном утверждении. Вы не можете сделать with temp as ... и попытаться использовать его после нескольких строк SQL. Вы можете иметь несколько CTE в одном выражении для более сложных запросов.

    Например,

     with temp1020 as (
        select id from dbo.fnFunctionName(10, 20)
    ),
    temp2030 as (
        select id from dbo.fnFunctionName(20, 30)
    )
    select * from temp1020 
    where id not in (select id from temp2030)
     
    ответ дан Rashmi Pandit, с репутацией 15757, 6.08.2009
  • 40 рейтинг

    Если таблица результатов вашего хранимого процесса слишком сложна для ввода инструкции «create table» вручную, и вы не можете использовать OPENQUERY или OPENROWSET, вы можете использовать sp_help для создания списка столбцов и типов данных для вас. Когда у вас есть список столбцов, это просто вопрос форматирования в соответствии с вашими потребностями.

    Шаг 1. Добавьте «в #temp» к выходному запросу (например, «выберите [...] в #temp из [...]»).

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

    Шаг 2. Запустите sp_help в таблице temp. (например, «exec tempdb..sp_help #temp»)

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

    Шаг 3. Скопируйте столбцы и типы данных в инструкцию create table

    У меня есть лист Excel, который я использую для форматирования вывода sp_help в оператор «create table». Вам не нужно ничего подобного, просто скопируйте и вставьте в свой редактор SQL. Используйте имена столбцов, их размеры и типы для создания инструкции «Создать таблицу #x [...]» или «declare @x table [...]», которую вы можете использовать для INSERT результатов хранимой процедуры.

    Шаг 4: Вставка во вновь созданную таблицу

    Теперь у вас будет запрос, похожий на другие решения, описанные в этом потоке.

     DECLARE @t TABLE 
    (
       --these columns were copied from sp_help
       COL1 INT,
       COL2 INT   
    )
    
    INSERT INTO @t 
    Exec spMyProc 
     

    Этот метод также может быть использован для преобразования таблицы temp ( #temp ) в переменную таблицы ( @temp ). Хотя это может быть больше шагов, чем просто запись инструкции create table , она предотвращает ручную ошибку, такую ​​как опечатки и несоответствия типа данных в больших процессах. Отладка опечатки может занять больше времени, чем писать запрос в первую очередь.

    ответ дан FistOfFury, с репутацией 2794, 31.07.2012
  • 28 рейтинг

    Quassnoi положил мне большую часть пути, но одна вещь отсутствовала:

    **** Мне нужно было использовать параметры в хранимой процедуре. ****

    И OPENQUERY не позволяет это произойти:

    Поэтому я нашел способ работать с системой, а также не должен делать определение таблицы таким жестким и переопределять его в другой хранимой процедуре (и, конечно, риск, что она может сломаться)!

    Да, вы можете динамически создать определение таблицы, возвращенное из хранимой процедуры, с помощью оператора OPENQUERY с фиктивными переменными (поскольку NO RESULT SET возвращает одинаковое количество полей и в том же положении, что и набор данных с хорошими данными).

    После создания таблицы вы можете использовать хранимую процедуру exec во временной таблице весь день.


    И отметить (как указано выше) вы должны включить доступ к данным,

     EXEC sp_serveroption 'MYSERVERNAME', 'DATA ACCESS', TRUE
     

    Код:

     declare @locCompanyId varchar(8)
    declare @locDateOne datetime
    declare @locDateTwo datetime
    
    set @locDateOne = '2/11/2010'
    set @locDateTwo = getdate()
    
    --Build temporary table (based on bogus variable values)
    --because we just want the table definition and
    --since openquery does not allow variable definitions...
    --I am going to use bogus variables to get the table defintion.
    
    select * into #tempCoAttendanceRpt20100211
    FROM OPENQUERY(DBASESERVER,
      'EXEC DATABASE.dbo.Proc_MyStoredProc 1,"2/1/2010","2/15/2010 3:00 pm"')
    
    set @locCompanyId = '7753231'
    
    insert into #tempCoAttendanceRpt20100211
    EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo
    
    set @locCompanyId = '9872231'
    
    insert into #tempCoAttendanceRpt20100211
    EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo
    
    select * from #tempCoAttendanceRpt20100211
    drop table #tempCoAttendanceRpt20100211
     

    Спасибо за информацию, которая была предоставлена ​​первоначально ... Да, наконец, мне не нужно создавать все эти фальшивые (строгие) таблицы при использовании данных из другой хранимой процедуры или базы данных, и да, вы также можете использовать параметры.

    Поисковые ссылки:

    • Хранимая процедура SQL 2005 в временную таблицу

    • openquery с хранимой процедурой и переменными 2005

    • openquery с переменными

    • выполнять хранимую процедуру в таблице temp

    Обновление: это не будет работать с временными таблицами, поэтому мне пришлось прибегать к ручному созданию временной таблицы.

    Замечание Bummer : это не будет работать с временными таблицами , http://www.sommarskog.se/share_data.html#OPENQUERY

    Ссылка: Следующее - определить LOCALSERVER. Он может выглядеть как ключевое слово в примере, но на самом деле это только имя. Вот как вы это делаете:

     sp_addlinkedserver @server = 'LOCALSERVER',  @srvproduct = '',
                       @provider = 'SQLOLEDB', @datasrc = @@servername
     

    Чтобы создать связанный сервер, вы должны иметь разрешение ALTER ANY SERVER или быть членом любой из фиксированных ролей сервера sysadmin или setupadmin.

    OPENQUERY открывает новое подключение к SQL Server. Это имеет некоторые последствия:

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

    Новое соединение имеет свою собственную базу данных по умолчанию (определенную с помощью sp_addlinkedserver, по умолчанию - master), поэтому вся спецификация объекта должна содержать имя базы данных.

    Если вы открыли транзакцию и удерживаете блокировки при вызове OPENQUERY, вызываемая процедура не сможет получить доступ к тем, что вы заблокируете. То есть, если вы не будете осторожны, вы заблокируете себя.

    Подключение осуществляется не бесплатно, поэтому есть штраф за производительность.

    ответ дан Doug Lubey of Louisiana, с репутацией 308, 11.02.2010
  • 23 рейтинг

    Если OPENROWSET вызывает проблемы, с 2012 года существует другой путь; используйте sys.dm_exec_describe_first_result_set_for_object, как указано здесь: Извлечь имена столбцов и типы хранимой процедуры?

    Во-первых, создайте эту хранимую процедуру для генерации SQL для временного

     CREATE PROCEDURE dbo.usp_GetStoredProcTableDefinition(
        @ProcedureName  nvarchar(128),
        @TableName      nvarchar(128),
        @SQL            nvarchar(max) OUTPUT
    )
    AS
    SET @SQL = 'CREATE TABLE ' + @tableName + ' ('
    
    SELECT @SQL = @SQL + '['+name +'] '+ system_type_name +''  + ','
            FROM sys.dm_exec_describe_first_result_set_for_object
            (
              OBJECT_ID(@ProcedureName), 
              NULL
            );
    
    --Remove trailing comma
    SET @SQL = SUBSTRING(@SQL,0,LEN(@SQL))    
    SET @SQL =  @SQL +')'
     

    Чтобы использовать процедуру, вызовите ее следующим образом:

     DECLARE     @SQL    NVARCHAR(MAX)
    
    exec dbo.usp_GetStoredProcTableDefinition
        @ProcedureName='dbo.usp_YourProcedure',
        @TableName='##YourGlobalTempTable',@SQL = @SQL OUTPUT
    
    INSERT INTO ##YourGlobalTempTable
    EXEC    [dbo].usp_YourProcedure
    
    select * from ##YourGlobalTempTable
     

    Обратите внимание, что я использую глобальную временную таблицу. Это потому, что использование EXEC для запуска динамического SQL создает свой собственный сеанс, поэтому обычная временная таблица выходит за рамки любого последующего кода. Если глобальная временная таблица является проблемой, вы можете использовать обычную временную таблицу, но любой последующий SQL должен быть динамическим, то есть также выполняться оператором EXEC.

    ответ дан StuartQ, с репутацией 2718, 5.02.2014
  • 18 рейтинг

    Эта сохраненная процедура выполняет задание:

     CREATE PROCEDURE [dbo].[ExecIntoTable]
    (
        @tableName          NVARCHAR(256),
        @storedProcWithParameters   NVARCHAR(MAX)
    )
    AS
    BEGIN
        DECLARE @driver         VARCHAR(10)
        DECLARE @connectionString   NVARCHAR(600)
        DECLARE @sql            NVARCHAR(MAX)
        DECLARE @rowsetSql      NVARCHAR(MAX)
    
        SET @driver = '''SQLNCLI'''
    
        SET @connectionString = 
            '''server=' + 
                CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)) + 
                COALESCE('\' + CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(256)), '') + 
            ';trusted_connection=yes'''
    
        SET @rowsetSql = '''EXEC ' + REPLACE(@storedProcWithParameters, '''', '''''') + ''''
    
        SET @sql = '
    SELECT
        *
    INTO 
        ' + @tableName + ' 
    FROM
        OPENROWSET(' + @driver + ',' + @connectionString + ',' + @rowsetSql + ')'
    
        EXEC (@sql)
    END
    GO
     

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

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

    ответ дан briantyler, с репутацией 6278, 26.09.2011
  • 14 рейтинг

    Если вам посчастливилось иметь SQL 2012 или выше, вы можете использовать dm_exec_describe_first_result_set_for_object

    Я только что отредактировал sql, предоставленный gotqn. Спасибо gotqn.

    Это создает глобальную таблицу temp с именем, аналогичным имени процедуры. После этого временную таблицу можно использовать по мере необходимости. Просто не забудьте бросить его перед повторным выполнением.

         declare @procname nvarchar(255) = 'myProcedure',
                @sql nvarchar(max) 
    
        set @sql = 'create table ##' + @procname + ' ('
        begin
                select      @sql = @sql + '[' + r.name + '] ' +  r.system_type_name + ','
                from        sys.procedures AS p
                cross apply sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r
                where       p.name = @procname
    
                set @sql = substring(@sql,1,len(@sql)-1) + ')'
                execute (@sql)
                execute('insert ##' + @procname + ' exec ' + @procname)
        end
     
    ответ дан Sandeep Gaadhe, с репутацией 167, 26.02.2016
  • 11 рейтинг

    Чтобы вставить первый набор записей хранимой процедуры во временную таблицу, вам необходимо знать следующее:

    1. только первая строка набора хранимой процедуры может быть вставлена ​​во временную таблицу
    2. хранимая процедура не должна выполнять динамический оператор T-SQL ( sp_executesql )
    3. вам нужно сначала определить структуру временной таблицы

    Вышеприведенное может выглядеть как ограничение, но ИМХО это имеет смысл - если вы используете sp_executesql вы можете сразу вернуть два столбца и один раз десять, а если у вас есть несколько наборов результатов, вы также не можете вставлять их в несколько таблиц - вы можете вставить максимум в двух таблицах в одном выражении T-SQL (с использованием предложения OUTPUT и без триггеров).

    Таким образом, проблема заключается главным образом в том, как определить временную структуру таблицы перед выполнением оператора EXEC ... INTO ... .

    Первый работает с OBJECT_ID а второй и третий - с Ad-hoc-запросами. Я предпочитаю использовать DMV вместо sp, так как вы можете использовать CROSS APPLY и создавать временные определения таблиц для нескольких процедур одновременно.

     SELECT p.name, r.* 
    FROM sys.procedures AS p
    CROSS APPLY sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r;
     

    Также обратите внимание на поле system_type_name как это может быть очень полезно. Он хранит полное определение столбца. Например:

     smalldatetime
    nvarchar(max)
    uniqueidentifier
    nvarchar(1000)
    real
    smalldatetime
    decimal(18,2)
     

    и вы можете использовать его непосредственно в большинстве случаев для создания определения таблицы.

    Итак, я думаю, что в большинстве случаев (если хранимая процедура соответствует определенным критериям) вы можете легко создавать динамические операторы для решения таких проблем (создавать временную таблицу, вставлять в нее результат хранимой процедуры, делать то, что вам нужно с данными) ,


    Обратите внимание, что указанные выше объекты не могут определить первые данные набора результатов в некоторых случаях, например, когда выполняются динамические инструкции T-SQL или временные таблицы используются в хранимой процедуре.

    ответ дан gotqn, с репутацией 17697, 3.06.2015
  • 11 рейтинг
    1. Я создаю таблицу со следующей схемой и данными.
    2. Создайте хранимую процедуру.
    3. Теперь я знаю, каков результат моей процедуры, поэтому я выполняю следующий запрос.

       CREATE TABLE [dbo].[tblTestingTree](
          [Id] [int] IDENTITY(1,1) NOT NULL,
          [ParentId] [int] NULL,
          [IsLeft] [bit] NULL,
          [IsRight] [bit] NULL,
      CONSTRAINT [PK_tblTestingTree] PRIMARY KEY CLUSTERED
      (
          [Id] ASC
      ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
      ) ON [PRIMARY]
      GO
      SET IDENTITY_INSERT [dbo].[tblTestingTree] ON
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (1, NULL, NULL, NULL)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (2, 1, 1, NULL)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (3, 1, NULL, 1)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (4, 2, 1, NULL)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (5, 2, NULL, 1)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (6, 3, 1, NULL)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (7, 3, NULL, 1)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (8, 4, 1, NULL)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (9, 4, NULL, 1)
      INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (10, 5, 1, NULL)
      
      SET IDENTITY_INSERT [dbo].[tblTestingTree] OFF
       

      VALUES (10, 5, 1, NULL) SET IDENTITY_INSERT [dbo]. [TblTestingTree] Вкл.

       create procedure GetDate
      as
      begin
          select Id,ParentId from tblTestingTree
      end
      
      create table tbltemp
      (
          id int,
          ParentId int
      )
      insert into tbltemp
      exec GetDate
      
      select * from tbltemp;
       
    ответ дан Devansh, с репутацией 767, 5.10.2013
  • 10 рейтинг

    Код

     CREATE TABLE #T1
    (
        col1 INT NOT NULL,
        col2 NCHAR(50) NOT NULL,
        col3 TEXT NOT NULL,
        col4 DATETIME NULL,
        col5 NCHAR(50) NULL,
        col6 CHAR(2) NULL,
        col6 NCHAR(100) NULL,
        col7 INT NULL,
        col8 NCHAR(50) NULL,
        col9 DATETIME NULL,
        col10 DATETIME NULL
    )
    
    DECLARE @Para1 int
    DECLARE @Para2 varchar(32)
    DECLARE @Para3 varchar(100)
    DECLARE @Para4 varchar(15)
    DECLARE @Para5 varchar (12)
    DECLARE @Para6 varchar(1)
    DECLARE @Para7 varchar(1)
    
    
    SET @Para1 = 1025
    SET @Para2 = N'6as54fsd56f46sd4f65sd'
    SET @Para3 = N'XXXX\UserName'
    SET @Para4 = N'127.0.0.1'
    SET @Para5 = N'XXXXXXX'
    SET @Para6 = N'X'
    SET @Para7 = N'X'
    
    INSERT INTO #T1
    (
        col1,
        col2,
        col3,
        col4,
        col5,
        col6,
        col6,
        col7,
        col8,
        col9,
        col10,
    )
    EXEC [dbo].[usp_ProcedureName] @Para1, @Para2, @Para3, @Para4, @Para5, @Para6, @Para6
     

    Надеюсь, это поможет. Пожалуйста, при необходимости.

    ответ дан SoftwareARM, с репутацией 969, 10.03.2011
  • 10 рейтинг

    Если запрос не содержит параметра, используйте OpenQuery else, используя OpenRowset .

    Основная задача - создать схему в соответствии с хранимой процедурой и вставить ее в эту таблицу. например:

     DECLARE @abc TABLE(
                      RequisitionTypeSourceTypeID INT
                    , RequisitionTypeID INT
                    , RequisitionSourcingTypeID INT
                    , AutoDistOverride INT
                    , AllowManagerToWithdrawDistributedReq INT
                    , ResumeRequired INT
                    , WarnSupplierOnDNRReqSubmission  INT
                    , MSPApprovalReqd INT
                    , EnableMSPSupplierCounterOffer INT
                    , RequireVendorToAcceptOffer INT
                    , UseCertification INT
                    , UseCompetency INT
                    , RequireRequisitionTemplate INT
                    , CreatedByID INT
                    , CreatedDate DATE
                    , ModifiedByID INT
                    , ModifiedDate DATE
                    , UseCandidateScheduledHours INT
                    , WeekEndingDayOfWeekID INT
                    , AllowAutoEnroll INT
                    )
    INSERT INTO @abc
    EXEC [dbo].[usp_MySp] 726,3
    SELECT * FROM @abc
     
    ответ дан ProblemSolver, с репутацией 389, 7.09.2015
  • 9 рейтинг

    Я обнаружил передачу массивов / данных в хранимые процедуры, которые могут дать вам еще одну идею о том, как вы можете решить свою проблему.

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

    Возможно, есть способ, которым это можно использовать с временной таблицей.

    ответ дан kevchadders, с репутацией 7304, 6.08.2009
  • 8 рейтинг

    Другой метод - создать тип и использовать PIPELINED, чтобы затем передать ваш объект. Однако это ограничивается знанием столбцов. Но это имеет то преимущество, что можно:

     SELECT * 
    FROM TABLE(CAST(f$my_functions('8028767') AS my_tab_type))
     
    ответ дан pierre, с репутацией 915, 11.08.2009
  • 7 рейтинг

    Я встретил ту же проблему, и вот что я сделал для этого из предложения Павла . Основная часть здесь состоит в том, чтобы использовать NEWID() чтобы избежать одновременного запуска нескольких процедур хранения / сценариев, боль для глобальной временной таблицы.

     DECLARE @sql varchar(max) = '', 
    @tmp_global_table varchar(255) = '##global_tmp_' + CONVERT(varchar(36), NEWID())
    SET @sql = @sql + 'select * into [' + @tmp_global_table + '] from YOURTABLE'
    EXEC(@sql)
    
    EXEC('SELECT * FROM [' + @tmp_global_table + ']')
     
    ответ дан zhongxiao37, с репутацией 759, 18.08.2014
  • 1 рейтинг

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

    ответ дан lakshmivisalij, с репутацией 42, 24.03.2015
  • -1 рейтинг

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

     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           
     
    ответ дан jmoreno, с репутацией 10637, 10.07.2018
  • -3 рейтинг

    Это можно сделать в 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
     

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

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

    ответ дан Matthew Baker, с репутацией 822, 27.01.2017
  • -5 рейтинг

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

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

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

    ответ дан Hlin, с репутацией 126, 19.08.2014