2010-08-18 3 views
7

저장 프로 시저를 작성 중이며 실패 할 경우 0 개의 레코드를 반환하려고합니다. 0 행을 반환하는 방법을 알아낼 수 없습니다? 나는 SELECT NULL을 사용했지만 행 1 col 1에 NULL이 1 행을 반환했습니다. SELECT 문을 내 오류 코드 경로에 지정하지 않았지만 SP 호출 후 @@ROWCOUNT 값을 테스트 할 때 1을 반환했습니다. 나는 @@ROWCOUNTEXISTS()에 속한 SELECT 성명 이전에 SP에서 재설정되지 않았기 때문일 것으로 생각합니다. 어떤 조언을 주시면 감사하겠습니다.T-SQL : 저장 프로 시저에서 0 행을 반환하는 방법 및 XACT_ABORT 및 TRY/CATCH를 사용하는 방법

또한 XACT_ABORT을 ON으로 설정했지만 TRY/CATCH 블록을 사용하여 저장 프로 시저에서 올바른 값 "반환 값"을 반환했는지 확인했습니다. 괜찮아? 오류가있는 경우 XACT_ABORTTRY/CATCH을 대체합니까, 아니면 내 오류 코드 경로가 올바른 반환 값을 반환할까요? 0 행을 반환하려면

-- Setup 
SET NOCOUNT ON; -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements. 
SET XACT_ABORT ON; -- SET XACT_ABORT ON rollback transactions on errors 
DECLARE @return int; SET @return = 1; -- Default to general error 

-- Start transaction 
BEGIN TRANSACTION 
    BEGIN TRY 

     IF NOT EXISTS(SELECT NULL FROM [MyTable] WHERE [Check] = 1) 
     BEGIN 

      -- Insert new record  
      INSERT INTO [MyTable] (Check, Date) VALUES (1, GETDATE()); 
      SELECT SCOPE_IDENTITY() AS [MyValue]; -- Return 1 row 
      SET @return = 0; -- Success 

     END 
     ELSE 
     BEGIN 

      -- Fail 
      SELECT NULL AS [MyValue]; -- Want to return 0 rows not 1 row with NULL 
      SET @return = 2; -- Fail error 

     END 

    END TRY 
    BEGIN CATCH 

     -- Error 
     ROLLBACK TRANSACTION; 
     SELECT NULL AS [MyValue]; -- Want to return 0 rows not 1 row with NULL 
     SET @return = 1; -- General error 

    END CATCH 

-- End transaction and return 
COMMIT TRANSACTION 
RETURN @return; 

답변

12

, 당신이 할 수 있습니다 : 개인적으로

SELECT TOP 0 NULL AS MyValue 

, 나는 결과 집합을 반환 밖으로 대신 다시 ID를 반환하는이 sproc에 대한 출력 매개 변수를 사용하십시오 - 그건 그냥 내 선호도. 그런 다음 해당 출력 매개 변수를 예 : 아무것도하지 않았 음을 나타내는 -1을 기본값으로 사용합니다.

+0

감사합니다! 나는 그 결과로부터 0 개의 결과를 얻고있다. :) 그러나 왜'EXEC MySP' 이후에 왜'@@ ROWCOUNT' = 1일까요? –

+0

'EXEC @ret = MySP; SET @rows = @@ ROWCOUNT; SELECT 'Rows'= @ rows'는 행 수만큼 1을 반환합니다. –

+0

아,'@@ ROWCOUNT'는 행에 영향을주는 명령문 (예 : INSERT 또는 UPDATE)에 대해서만 변경됩니다. –

1

이 내가 할 거라고하는 방법이다 : 빠른 응답

CREATE PROCEDURE YourProcedure 
AS 
( @NewMyValue int OUTPUT --<<<<<use output parameter and not a result set 
) 
BEGIN TRY 

    --<<<<put everything in the BEGIN TRY!!! 

    -- Setup 
    SET NOCOUNT ON; -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements. 
    SET XACT_ABORT ON; -- SET XACT_ABORT ON rollback transactions on errors 
    DECLARE @return int 

    --<<init multiple variables in a select, it is faster than multiple SETs 
    --set defaults 
    SELECT @return = 1  -- Default to general error 
      ,@NewMyValue=NULL 

    -- Start transaction 
    BEGIN TRANSACTION --<<<put the transaction in the BEGIN TRY 

    --<<<lock rows for this transaction using UPDLOCK & HOLDLOCK hints 
    IF NOT EXISTS(SELECT NULL FROM [MyTable] WITH (UPDLOCK, HOLDLOCK) WHERE [Check] = 1) 
    BEGIN 
      -- Insert new record  
     INSERT INTO [MyTable] (Check, Date) VALUES (1, GETDATE()); 
     SELECT @NewMyValue=SCOPE_IDENTITY() --<<<set output parameter, no result set 
       ,@return = 0; -- Success 
    END 
    ELSE 
    BEGIN 
     -- Fail 
     --<<no need for a result set!!! output parameter was set to a default of NULL 
     SET @return = 2; -- Fail error 
    END 

    COMMIT TRANSACTION --<<<commit in the BEGIN TRY!!! 
END TRY 
BEGIN CATCH 
    -- Error 
    IF XACT_STATE()!=0 --<<<only rollback if there is a bad transaction 
    BEGIN 
     ROLLBACK TRANSACTION 
    END 
    --<<any insert(s) into log tables, etc 
    --<<no need for a result set!!! output parameter was set to a default of NULL 
    SET @return = 1; -- General error 
END CATCH 

-- End transaction and return 
RETURN @return; 
GO 
관련 문제