MSTSQL: может ли SP возвращать как выходной параметр, так и результирующий набор

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

create procedure uspReadMyXmlInformation(@myXmlDoc xml, @myProductNum varchar(18) output) as
    begin
        set nocount on;

        declare @myXmlContent table(MyOrderId varchar(12) not null
                                   ,CreatedAt datetime not null)

        insert into @myXmlContent
            select x.c.value('MyOrderID[1]', 'varchar(12)')
                    x.c.value('CreatedAt[1]', 'datetime')
                from @myXmlDoc.nodes('MyRootNodeName/MyChildNodeName') x(c)

        set @myProductNum='MyProductNum'

        select *
            from @myXmlContent

        return;
    end

Итак, здесь происходит то, что я могу либо получить результирующий набор, когда я удаляю выходной параметр, либо я получаю выходной параметр, а результирующий набор всегда пуст (0=count(*)).

В любом случае я могу получить оба с помощью одной и той же хранимой процедуры, или мне лучше разделить их?

Я думаю, что это выполнимо из этого поста в Oracle. Я хотел бы добиться того же в SQL Server, хотя и ограничен версией 2008 года.

Хранимая процедура Oracle: вернуть как результирующий набор, так и выходные параметры< /а>

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

ИЗМЕНИТЬ

Как некоторые думают, это может быть дубликат:

Возможно вернуть параметр вывода с помощью DataReader

Я не думаю, что ответы связаны с тем, как ведет себя DataReader, а не с тем, как этого можно достичь с помощью TSQL.

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

Итак, я работаю только над проектом SQL Server, и мне это нужно. В противном случае я разделю его на две части, если не смогу добиться этого своевременно.

Вот как это используется:

declare @xmlInformationData table(MyOrderId varchar(12) not null
                                  ,CreatedAt datetime not null)
insert into @xmlInformationData
    execute uspReadMyXmlInformation @myXmlDoc, @myProductNum output

while 0<(select count(*) from @xmlInformationData)
    begin
        -- This will never be executed because I have no rows in @xmlInformationData
        -- And yet, before the loop, I have my out param value!
    end

person Will Marcouiller    schedule 08.02.2019    source источник
comment
Вы можете иметь оба, но выходные параметры могут быть заполнены поздно, например. после закрытия DataReader в приложении .NET.   -  person HABO    schedule 08.02.2019
comment
Как говорит @HABO, вы можете иметь и то, и другое, но переменные out обычно доступны только после обработки последнего набора результатов.   -  person Lucero    schedule 08.02.2019
comment
На самом деле нет никакого DataReader! Я не знаю, где вы, ребята, видели тег C# или что-то подобное, но его нет! Это проект только для SQL Server, так как эта база данных предназначена для обмена данными. Итак, он идет и читает данные из стороны в сторону и проталкивает информацию. Итак, никакого C#-кода! Итак, теперь я получаю значение выходного параметра, но никогда не получаю данные результирующего набора. И мне нужны оба. Кто-нибудь может помочь?   -  person Will Marcouiller    schedule 10.02.2019
comment
@HABO, пожалуйста, смотрите комментарий выше. Нет DataReader, нет кода C#. Я не знаю, где вы его подобрали. Итак, я добавил пример использования, который ясно показывает, что он используется в другом вызове процедуры.   -  person Will Marcouiller    schedule 10.02.2019
comment
@Lucero Тогда это должно быть что-то с моим XML. Возможно, я что-то путаю, так как мне приходится много манипулировать этим, например читать его значения в табличную переменную, вводить недостающую информацию, а затем преобразовывать ее обратно в XML и передавать другой процедуре для дальнейшей обработки. Это сделано для максимального повторного использования кода в рабочем процессе. Спасибо за этот ваш скриншот. Я помог.   -  person Will Marcouiller    schedule 10.02.2019


Ответы (1)


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

create procedure Arthur( @TheAnswer as Int Output ) as
  begin

  -- Set the value of the output parameter.
  set @TheAnswer = 42;

  -- Generate a single row most of the time.
  select GetDate() as NextVogonPoetryReading
    where DatePart( millisecond, GetDate() ) < 750;

  end;
go 1

-- Declare the variables for the test.
declare @HHGTTU as Table ( HHGTTUId Int Identity, NextVogonPoetryReading DateTime );
declare @SixTimesNine as Int;

-- Execute the SP once so that the   while   loop might.
insert into @HHGTTU ( NextVogonPoetryReading )
  execute Arthur @TheAnswer = @SixTimesNine Output;

-- See what happens.
while exists ( select Pi() from @HHGTTU )
  begin
  -- See where we are at.
  select @SixTimesNine as SixTimesNine, Max( HHGTTUId ) as MaxHHGTTUId, Max( NextVogonPoetryReading ) as MaxNextVogonPoetryReading
    from @HHGTTU;
  -- Reset.
  delete from @HHGTTU;
  set @SixTimesNine = 54;
  select @SixTimesNine as SixTimesNineAfterReset;
  waitfor delay '00:00:00.100';
  -- Execute the SP again.
  insert into @HHGTTU ( NextVogonPoetryReading )
    execute Arthur @TheAnswer = @SixTimesNine Output;
  end;

В сторону: приношу свои извинения за травму, причиненную вам моим упоминанием о DataReader. Я просто пытался передать свой опыт работы с приложением C#, не вдаваясь в подробности того, какое именно соединение с базой данных вы используете, какие драйверы могут быть задействованы, ....

person HABO    schedule 10.02.2019
comment
Создание теста со случайными результатами, как вы, кажется не очень разумным, так как в 25% случаев это будет отображать неудачный тестовый пример исходной проблемы. - person Lucero; 11.02.2019
comment
@Lucero Намерение состояло в том, чтобы предоставить пример, который завершается и имеет различное поведение, в том числе иногда возвращает нулевые строки, но всегда возвращает выходной параметр. В нем рассматривается вопрос в заголовке сообщения OP: может ли SP возвращать как выходной параметр, так и набор результатов. Это не решает проблему OP, когда неудачный случай заключается в том, что возможен только один или другой вывод, но никогда оба. - person HABO; 11.02.2019
comment
Достаточно честно, я не минусовал или что-то в этом роде, а просто указал, что результат 0-row-result здесь не является хорошим примером. Что-то вроде 1 или 2 строк было бы лучше, если вы хотите иметь случайность. :) - person Lucero; 11.02.2019
comment
На самом деле моя проблема заключалась в том, что у меня была эта процедура, возвращающая набор результатов и выходной параметр, на третьем уровне иерархии, что не очень нравится MSSQL. Вместо этого мне пришлось использовать табличную функцию и отдельную скалярную функцию. И поскольку мне не нравилась эта мода, я переработал свой код по-другому, и да, теперь моя процедура uspReadXmlDataInformation безупречно возвращает нужную информацию. Таким образом, мораль этой истории заключается в том, чтобы не выстраиваться над двумя вложенными наборами результатов SP, иначе возникает странное поведение. - person Will Marcouiller; 28.02.2019