IT이야기

SQL Server의 다른 저장 프로시저에서 호출된 저장 프로시저의 SELECT 출력을 억제하는 방법

cyworld 2021. 10. 1. 21:26
반응형

SQL Server의 다른 저장 프로시저에서 호출된 저장 프로시저의 SELECT 출력을 억제하는 방법은 무엇입니까?


"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에 약 50k 레코드가 있다고 가정해 보겠습니다. 해당 SP는 50,000번 호출되어 50,000개의 xml 문자열을 출력 창에 기록합니다. 그것은 SQL 서버를 중지시키지 않고 내 클라이언트 앱(sql 서버 관리 스튜디오)만 가져왔습니다.


찾고 있는 답변 은 Josh Burke 유사한 SO 질문 에서 찾을 수 있습니다 .

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

내가 찾은 것 같아요 솔루션을.

이제 내 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과 유사한 기능이 있습니까? 널 테이블이나 뭔가요?


"저장 프로시저 출력을 어떻게 억제합니까?"라는 질문에 대답합니다. 실제로 달성하려는 것에 달려 있습니다. 그래서 저는 제가 겪은 일에 기여하고 싶습니다.

출력에서 행 수(@@ROWCOUNT)를 원했기 때문에 저장 프로시저(USP) 출력을 억제해야 했습니다. 내가 한 일은 모든 사람에게 작동하지 않을 수 있습니다. 내 쿼리가 이미 동적 SQL이 될 것이기 때문에 문제의 USP에 @silentExecution이라는 매개 변수를 추가했습니다. 이것은 내가 기본적으로 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 Server를 떠나지 않습니다. ExecuteNonQuery를 사용하여 프로시저를 호출할 수도 있습니다.

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

Here the client won't even ask for the result of the select.


I have recently come across with a similar issue while writing a migration script and since the issue was resolved in a different way, I want to record it. I have nearly killed my SSMS Client by running a simple while loop for 3000 times and calling a procedure.

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

The script result was executed using SSMS and default option on query window is set to show “Results to Grid”[Ctrl+d shortcut].

Easy Solution: Try setting the results to file to avoid the grid to be built and painted on the SSMS client. [CTRL+SHIFT+F keyboard shortcut to set the query results to file].

This issue is related to : stackoverflow query


You could create a SQL CLR stored procedure that execs this. Should be pretty easy.


I don't know if SQL Server has an option to suppress output (I don't think it does), but the SQL Query Analyzer has an option (under results tab) to "Discard Results".

Are you running this through isql?


You said your server is crashing. What is crashing the application that consumes the output of this SQL or SQL Server itself (assuming SQL Server).

If you are using .Net Framework application to call the stored procedure then take a look at SQLCommand.ExecuteNonQuery. This just executes stored procedure with no results returned. If problem is at SQL Server level then you are going to have to do something different (i.e. change the stored procedure).


ever tried SET NOCOUNT ON; as an option?

ReferenceURL : https://stackoverflow.com/questions/866484/how-to-suppress-the-select-output-of-a-stored-procedure-called-from-another-stor

반응형