Доступ к наборам результатов из хранимых процедур Transact-SQL SQL Server

StackOverflow https://stackoverflow.com/questions/58940

  •  09-06-2019
  •  | 
  •  

Вопрос

Я использую SQL Server 2005 и хотел бы знать, как получить доступ к различным наборам результатов из transact-sql.Следующая хранимая процедура возвращает два набора результатов. Как мне получить к ним доступ, например, из другой хранимой процедуры?

CREATE PROCEDURE getOrder (@orderId as numeric) AS
BEGIN   
    select order_address, order_number from order_table where order_id = @orderId
    select item, number_of_items, cost from order_line where order_id = @orderId
END

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

РЕДАКТИРОВАТЬ:Просто чтобы прояснить вопрос, я хочу протестировать хранимые процедуры.У меня есть набор хранимых процедур, которые используются клиентом VB.NET и возвращают несколько наборов результатов.Они не будут заменены на функции с табличным значением, на самом деле я вообще не могу изменить процедуры.Изменение процедуры не является вариантом.

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

Это было полезно?

Решение

Краткий ответ:ты не сможешь этого сделать.

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

Для полноты картины: если процедура возвращала один результат, вы можете вставить его во временную таблицу или табличную переменную, используя следующий синтаксис:

INSERT INTO #Table (...columns...)
EXEC MySproc ...parameters...

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

Другие советы

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

Видите ли, новый SqlDataAdapter по умолчанию заполнит процедуру с несколькими наборами результатов в набор данных с несколькими таблицами.Данные в этих таблицах, в свою очередь, можно вставить в таблицы #Temp вызывающей процедуры, которую вы хотите записать. набор данных.ReadXmlSchema покажет вам схему каждого набора результатов.

Шаг 1:Начните писать процедуру, которая будет считывать данные из процедуры с множеством результатов.

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

CREATE PROCEDURE [dbo].[usp_SF_Read] AS
SET NOCOUNT ON;
CREATE TABLE #Table01 (Document_ID VARCHAR(100)
  , Document_status_definition_uid INT
  , Document_status_Code VARCHAR(100) 
  , Attachment_count INT
  , PRIMARY KEY (Document_ID));

б.На этом этапе вам может потребоваться объявить курсор для многократного вызова процедуры CLR, которую вы создадите здесь:

Шаг 2:Создайте процедуру CLR

Partial Public Class StoredProcedures
    <Microsoft.SqlServer.Server.SqlProcedure()> _
    Public Shared Sub usp_SF_ReadSFIntoTables()

    End Sub
End Class

а.Подключитесь с помощью New SqlConnection("context connection=true").

б.Настройте командный объект (cmd), содержащий процедуру с набором множественных результатов.

в.Получите все данные, используя следующее:

    Dim dataset As DataSet = New DataSet
    With New SqlDataAdapter(cmd)
        .Fill(dataset) ' get all the data.
    End With
'you can use dataset.ReadXmlSchema at this point...

д.Переберите каждую таблицу и вставьте каждую строку в соответствующую временную таблицу (которую вы создали на первом этапе выше).

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

Вот и все!

~ Шон, недалеко от Сиэтла

Есть еще одна хитрость, которую вы тоже можете сделать.Добавьте необязательный параметр N int в вашу процедуру.По умолчанию значение N равно -1.Если значение N равно -1, выполните каждый свой выбор.В противном случае сделайте N-й выбор и только N-й выбор.

Например,

if (N = -1 or N = 0)
    select ...

if (N = -1 or N = 1)
    select ...

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

Обратите внимание, что существует дополнительное недокументированное ограничение для INSERT INTO...Заявление Исполнительного директора:он не может быть вложенным.То есть хранимая процедура, которую вызывает EXEC (или любая другая, которую он вызывает в свою очередь), не может сама выполнить INSERT INTO...ИСПОЛНИТЕЛЬ.Похоже, что для каждого процесса существует один блокнот, который накапливает результаты, и если они вложены, вы получите сообщение об ошибке, когда вызывающий объект откроет его, а затем вызываемый попытается открыть его снова.

Матье, вам нужно будет вести отдельные временные таблицы для каждого «типа» результата.Кроме того, если вы выполняете одно и то же несколько раз, вам может потребоваться добавить к этому результату дополнительный столбец, чтобы указать, каким вызовом он стал.

К сожалению, сделать это невозможно.Проблема, конечно, в том, что не существует синтаксиса SQL, позволяющего это сделать.Конечно, это происходит «под капотом», но вы не можете получить другие результаты в TSQL, только из приложения через ODBC или что-то еще.

Есть способ обойти это, как и в большинстве случаев.Хитрость заключается в том, чтобы использовать устаревшую автоматизацию в TSQL для создания объекта ADODB, который по очереди открывает каждый набор результатов и записывает результаты в назначенные вами таблицы (или делает с наборами результатов все, что захотите).вы также можете сделать это в DMO, если вам нравится боль.

Есть два способа легко это сделать.Либо поместите результаты во временную таблицу, а затем обратитесь к временной таблице из своей процедуры.Другая альтернатива — поместить результаты в переменную XML, которая используется в качестве переменной OUTPUT.

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

XML может потребовать много памяти и работать медленно.

Вы можете выбрать их во временные таблицы или написать табличные функции для возврата наборов результатов.Спрашиваете, как перебирать наборы результатов?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top