Как вернуть временную таблицу из хранимой процедуры - PullRequest
15 голосов
/ 18 сентября 2009
CREATE PROCEDURE [test].[proc]
@ConfiguredContentId int,
@NumberOfGames int
AS
BEGIN
 SET NOCOUNT ON
 RETURN 
 @WunNumbers TABLE (WinNumb int)

    INSERT INTO @WunNumbers (WinNumb)
 SELECT TOP (@NumberOfGames) WinningNumber
 FROM [Game].[Game] g
 JOIN [Game].[RouletteResult] AS rr ON g.[Id] = rr.[gameId]
 WHERE g.[ConfiguredContentId] = @ConfiguredContentId
 ORDER BY g.[Stoptime] DESC

 SELECT WinNumb, COUNT (WinNumb) AS "Count"
 FROM @WunNumbers wn
 GROUP BY wn.[WinNumb]
END
GO

Эта хранимая процедура возвращает значения из первого оператора выбора, но я хотел бы, чтобы значения из второго оператора выбора были возвращены. Таблица @WunNumbers является временной таблицей.

Есть идеи ???

Ответы [ 6 ]

27 голосов
/ 18 сентября 2009

Посмотрите на этот код,

CREATE PROCEDURE Test

AS
    DECLARE @tab table (no int, name varchar(30))

    insert @tab  select eno,ename from emp  

    select * from @tab
RETURN
6 голосов
/ 18 сентября 2009

Какую версию SQL Server вы используете? В SQL Server 2008 вы можете использовать Параметры таблицы и типы таблиц .

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

Вы можете найти пример здесь

3 голосов
/ 03 июля 2012

В вызывающей стороне может быть создана временная таблица, а затем заполнена из вызываемого SP.

  create table #GetValuesOutputTable(
     ...   
  );

  exec GetValues; -- populates #GetValuesOutputTable

  select * from #GetValuesOutputTable;

Некоторые преимущества этого подхода перед «insert exec» состоят в том, что он может быть вложенным и может использоваться как вход или выход.

Некоторые недостатки заключаются в том, что «аргумент» не является публичным, создание таблицы существует внутри каждого вызывающего, и что имя таблицы может конфликтовать с другими временными объектами. Помогает, когда имя временной таблицы близко соответствует имени SP и соответствует некоторому соглашению.

Если взять немного дальше, то для вывода только временных таблиц вызываемый SP может одновременно поддерживать подход insert-exec и подход временных таблиц. Это не слишком помогает для цепочки SP, потому что таблицу все еще нужно определить в вызывающей стороне, но может помочь упростить тестирование из строки cmd или при внешнем вызове.

  -- The "called" SP
  declare
      @returnAsSelect bit = 0;

  if object_id('tempdb..#GetValuesOutputTable') is null
  begin
      set @returnAsSelect = 1;
      create table #GetValuesOutputTable(
         ...   
      );
  end

  -- populate the table

  if @returnAsSelect = 1
      select * from #GetValuesOutputTable;
1 голос
/ 21 июля 2017

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

В SP используйте INSERT для загрузки данных во временную таблицу в соответствии с тем же соглашением об именах, например, # SPName_Output , который предполагается существующим. Вы можете проверить его наличие и вернуть ошибку, если это не так.

Перед вызовом sp используйте этот простой выбор для создания временной таблицы:

SELECT TOP(0) * INTO #SPName_Output FROM tmp_SPName_Output;
EXEC SPName;
-- Now process records in #SPName_Output;

Это имеет следующие явные преимущества:

  • Временная таблица является локальной для текущего сеанса, в отличие от ##, поэтому не будет конфликтовать с параллельными вызовами SP из разные сессии. Он также автоматически удаляется при выходе из области видимости.
  • Таблица шаблонов поддерживается вместе с SP, поэтому, если изменения сделано к выводу (например, добавлены новые столбцы), а затем уже существует абоненты ИП не ломаются. Звонящий не нужно менять.
  • Вы можете определить любое количество выходных таблиц с разными именами для один SP и заполните их все. Вы также можете определить альтернативные выходы с разными именами и пусть SP проверит наличие временного таблицы, чтобы увидеть, какие должны быть заполнены.
  • Аналогичным образом, если внесены серьезные изменения, но вы хотите сохранить в обратном направлении совместимость, вы можете иметь новую таблицу шаблонов и названия для более поздней версия, но все еще поддерживает более раннюю версию, проверив, какой темп таблица, созданная вызывающим абонентом.
0 голосов
/ 05 декабря 2014

ДА ВЫ МОЖЕТЕ.

В своей хранимой процедуре вы заполняете таблицу @tbRetour.

В самом конце вашей хранимой процедуры вы пишете:

SELECT * FROM @tbRetour 

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

USE [...]
GO

DECLARE @return_value int

EXEC @return_value = [dbo].[getEnregistrementWithDetails]
@id_enregistrement_entete = '(guid)'

GO
0 голосов
/ 18 сентября 2009

Возвращаемый тип процедуры int.

Вы также можете возвращать наборы результатов (как ваш код в настоящее время делает) (хорошо, вы также можете отправлять сообщения, которые являются строками)

Это единственные «возвраты», которые вы можете сделать. Хотя в процедуру можно добавить табличные параметры (см. BOL), они только для ввода.

Edit:

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

...