Как подавить вывод SELECT хранимой процедуры, вызванной из другой хранимой процедуры в SQL Server? - PullRequest
52 голосов
/ 15 мая 2009

Я не говорю о выполнении "SET NOCOUNT OFF". Но у меня есть хранимая процедура, которую я использую, чтобы вставить некоторые данные в некоторые таблицы. Эта процедура создает строку ответа xml, позвольте мне привести пример:

CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
DECLARE @reply varchar(2048)

... Do a bunch of inserts/updates...

SET @reply = '<xml><big /><outputs /></xml>'
SELECT @reply
GO

Итак, я собрал скрипт, который использует этот SP несколько раз, и «выходной» xml становится слишком большим (он уже однажды разбил мой ящик).

Есть ли способ подавить или перенаправить вывод, сгенерированный из этой хранимой процедуры? Я не думаю, что изменение этой хранимой процедуры является опцией.

спасибо.


Полагаю, мне следует уточнить. Этот SP выше вызывается сценарием обновления T-SQL, который я написал, для запуска через менеджер студии предприятия и т. Д.

И это не самый элегантный SQL, который я когда-либо писал (некоторые psuedo-sql):

WHILE unprocessedRecordsLeft
  BEGIN
    SELECT top 1 record from updateTable where Processed = 0
    EXEC insertSomeData @param = record_From_UpdateTable
  END

Допустим, в UpdateTable содержится около 50 тыс. Записей. Этот SP вызывается 50k раз, записывая 50k строк XML в окно вывода. Это не привело к остановке сервера sql, только мое клиентское приложение (студия управления сервером sql).

Ответы [ 10 ]

36 голосов
/ 15 августа 2014

Ответ, который вы ищете, найден в аналогичном вопросе Джоша Бёрка:

-- Assume this table matches the output of your procedure
DECLARE @tmpNewValue TABLE ([Id] int, [Name] varchar(50))

INSERT INTO @tmpNewValue 
  EXEC ProcedureB

SELECT * FROM @tmpNewValue
27 голосов
/ 15 мая 2009

Я думаю, что нашел решение.

Итак, что я могу сделать сейчас в своем SQL-скрипте, примерно так (код sql-psuedo):

create table #tmp(xmlReply varchar(2048))
while not_done
  begin
    select top 1 record from updateTable where processed = 0
    insert into #tmp exec insertSomeData @param=record
  end
drop table #tmp

Теперь, если бы был еще более эффективный способ сделать это. Есть ли в SQL Server что-то похожее на / dev / null? Нулевой стол или что-то еще?

9 голосов
/ 15 апреля 2011

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

Мне нужно было подавить вывод хранимой процедуры (USP), потому что я просто хотел получить количество строк (@@ ROWCOUNT) из вывода. То, что я сделал, и это может не сработать для всех, так как мой запрос уже собирался быть динамическим, я добавил параметр под названием @silentExecution в рассматриваемый USP. Это битовый параметр, который по умолчанию установлен на ноль (0).

Далее, если @silentExecution было установлено равным единице (1), я бы вставил содержимое таблицы во временную таблицу, которая будет подавлять вывод, а затем без проблем выполнить @@ ROWCOUNT.

USP Пример:

CREATE PROCEDURE usp_SilentExecutionProc
    @silentExecution bit = 0
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @strSQL VARCHAR(MAX);

    SET @strSQL = '';

    SET @strSQL = 'SELECT TOP 10 * ';

    IF @silentExecution = 1
         SET @strSQL = @strSQL + 'INTO #tmpDevNull ';

    SET @strSQL = @strSQL +     
    'FROM dbo.SomeTable ';

    EXEC(@strSQL);
END
GO

Тогда вы можете выполнить все это так:

EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;

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

Просто хотел поделиться своим решением.

5 голосов
/ 15 мая 2009

Чувак, это действительно тот случай, когда компьютер делает то, что вы сказали ему делать вместо того, что вы хотели сделать.

Если вы не хотите, чтобы он возвращал результаты, не просите , чтобы он возвращал результаты. Рефакторинг хранимой процедуры на две части:

CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
BEGIN
DECLARE @reply varchar(2048)

--... Do a bunch of inserts/updates...

EXEC SelectOutput
END
GO

CREATE PROCEDURE SelectOutput AS
BEGIN
SET @reply = '<xml><big /><outputs /></xml>'
SELECT @reply
END
2 голосов
/ 09 января 2014

Недавно я сталкивался с подобной проблемой при написании сценария миграции, и, поскольку проблема была решена другим способом, я хочу ее записать. Я чуть не убил свой клиент SSMS, выполнив простой цикл while 3000 раз и вызвав процедуру.

DECLARE @counter INT
SET @counter = 10
WHILE @counter > 0 
BEGIN 
    -- call a procedure which returns some resultset
    SELECT  @counter-- (simulating the effect of stored proc returning some resultset)
    SET @counter = @counter - 1
END

Результат сценария был выполнен с использованием SSMS, и в окне запроса по умолчанию установлено отображение «Результаты в сетку» [сочетание клавиш Ctrl + d].

Простое решение: Попробуйте установить результаты в файл, чтобы избежать построения и раскраски сетки на клиенте SSMS. [Сочетание клавиш CTRL + SHIFT + F для установки результатов запроса в файл].

Эта проблема связана с: запрос stackoverflow

2 голосов
/ 15 мая 2009

С какого клиента вы вызываете хранимую процедуру? Скажем, это было из C #, и вы называете это как:

var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
var read = com.ExecuteReader();

Это еще не приведет к получению результата с сервера; для этого вы должны вызвать Read ():

read.Read();
var myBigString = read[0].ToString();

Так что, если вы не вызовете Read, XML не покинет Sql Server. Вы даже можете вызвать процедуру с ExecuteNonQuery:

var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
com.ExecuteNonQuery();

Здесь клиент даже не будет запрашивать результат выбора.

1 голос
/ 15 мая 2009

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

0 голосов
/ 27 ноября 2009

когда-нибудь пробовал SET NOCOUNT ON; как вариант?

0 голосов
/ 15 мая 2009

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

Если вы используете приложение .Net Framework для вызова хранимой процедуры, взгляните на SQLCommand.ExecuteNonQuery. Это просто выполняет хранимую процедуру без результатов. Если проблема на уровне SQL Server, то вам придется сделать что-то другое (т.е. изменить хранимую процедуру).

0 голосов
/ 15 мая 2009

Я не знаю, есть ли в SQL Server опция подавления вывода (я так не думаю), но в SQL Query Analyzer есть опция (на вкладке результатов) «Отменить результаты».

Вы запускаете это через isql?

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