Как подавить вывод 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

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

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

спасибо.


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

И это не самый элегантный 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).

Ответ 1

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

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

Ответ 2

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

-- 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

Ответ 3

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

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

Далее, если для параметра @silentExecution установлено значение 1 (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 мог возвращать результирующий набор в других целях или случаях, но все равно использовать его только для строк.

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

Ответ 4

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

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

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

Ответ 5

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

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();

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

Ответ 6

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

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

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

Эта проблема связана с: fooobar.com/questions/145110/...

Ответ 7

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

Ответ 8

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

Выполняете ли вы это через isql?

Ответ 9

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

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

Ответ 10

когда-либо пробовал SET NOCOUNT ON; в качестве опции?