Как подавить вывод SELECT хранимой процедуры, вызванной из другой хранимой процедуры в SQL Server?



Я не говорю о том, чтобы сделать "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, который я написал,для запуска через enterprise studio manager и т. д.



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



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


Итак, предположим, что UpdateTable имеет в себе около 50k записей. Этот SP вызывается 50k раз, записывая 50k xml-строк в окно вывода. Оно не принесло sql server до упора, просто мое клиентское приложение (SQL server management studio).

1208   10  

10 ответов:

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

Так что теперь я могу сделать в своем 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? Нуль-таблица или что-то в этом роде?

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

/* Assume this table matches the output of your procedure */
DECLARE @tmpNewValue TABLE (newvalue int)

INSERT INTO @tmpNewValue 
  EXEC ProcedureB

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

Мне нужно было подавить вывод хранимой процедуры (USP), потому что я просто хотел получить количество строк (@@ROWCOUNT) из вывода. То, что я сделал, и это может не сработать для всех, так как мой запрос уже собирался быть динамическим sql, я добавил параметр под названием @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 мог возвращать результирующий набор в других целях или случаях, но все же использовать его только для строки.

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

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

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

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

Из какого клиента вы вызываете хранимую процедуру? Скажите, что это было из 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-сервер. Вы даже можете вызвать процедуру с помощью ExecuteNonQuery:

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

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

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

Недавно я столкнулся с подобной проблемой при написании сценария миграции, и поскольку проблема была решена другим способом, я хочу записать ее. Я почти убил своего клиента 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 shortcut].

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

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

Я не знаю, есть ли у SQL Server возможность подавлять вывод (я не думаю, что это так), но анализатор запросов SQL имеет возможность (на вкладке Результаты) "отбрасывать результаты".

Вы прогоняете это через isql?

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

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

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

Comments

    Ничего не найдено.