programing

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

css3 2023. 6. 29. 20:18

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

"SET NO COUNT 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,000개의 레코드가 있다고 가정해 보겠습니다.이 SP는 50k번 호출되어 출력 창에 50k 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 [Id], [Name] FROM @tmpNewValue

해결책을 찾은 것 같아요.

이제 SQL 스크립트에서 수행할 수 있는 작업은 다음과 같습니다(sql-puedo 코드).

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이 될 예정이었기 때문에 @silentExecution이라는 매개 변수를 문제의 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가 다른 용도나 사례에서 결과 집합을 반환하면서도 행에만 사용할 수 있도록 하는 것입니다.

그냥 내 해결책을 공유하고 싶었어요.

최근 마이그레이션 스크립트를 작성하는 중에 비슷한 문제가 발생했는데 다른 방법으로 문제가 해결되었기 때문에 기록하려고 합니다.저는 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를 사용하여 실행되었으며 쿼리 창의 기본 옵션이 "Results to Grid"를 표시하도록 설정되었습니다.[Ctrl+d 바로 가기].

간편한 솔루션:SSMS 클라이언트에서 그리드가 빌드되고 칠해지지 않도록 결과를 파일로 설정합니다.[CTRL+Shift+F 바로 가기 키를 눌러 쿼리 결과를 파일로 설정].

이 문제는 다음과 관련이 있습니다. 스택 오버플로 쿼리

이런, 이건 컴퓨터가 여러분이 원하는 것 대신에 여러분이 하라고 한 것을 하는 심각한 경우입니다.

결과를 반환하지 않으려면 결과를 반환하도록 요청하지 마십시오.저장 프로시저를 두 개로 리팩터링합니다.

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

여기서 고객은 선택 결과를 묻지도 않습니다.

이를 실행하는 SQL CLR 저장 프로시저를 생성할 수 있습니다.꽤 쉬울 겁니다.

SQL Server에 출력을 억제하는 옵션이 있는지 알 수 없지만(그렇지 않은 것 같습니다) SQL Query Analyzer에는 "Discard Results(결과 삭제)이 있습니다.

당신은 isql을 통해 이것을 실행하고 있습니까?

당신의 서버가 다운되고 있다고 말씀하셨습니다.이 SQL 또는 SQL 서버 자체의 출력을 소비하는 애플리케이션을 중단시키는 원인(SQL 서버로 가정).

를 사용하는 경우.NetFramework 응용 프로그램에서 저장 프로시저를 호출한 다음 SQL Command를 살펴봅니다.비쿼리를 실행합니다.결과를 반환하지 않고 저장 프로시저만 실행합니다.문제가 SQL Server 수준이면 다른 작업(예: 저장 프로시저 변경)을 수행해야 합니다.

SP에 매개 변수를 포함하여 선택 여부를 지정할 수 있지만 SP에 액세스하고 다시 프로그래밍해야 합니다.

  CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int, @doSelect bit=1) AS
DECLARE @reply varchar(2048)

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

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

해본 적이 없는SET NOCOUNT ON;선택사항으로?

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