2010-08-18 24 views
7

Tôi đang viết một thủ tục đã lưu và tôi muốn trả về 0 bản ghi khi có lỗi. Tôi không thể tìm ra cách để trả về 0 hàng? Tôi đã sử dụng SELECT NULL nhưng điều này trả về 1 hàng với NULL trong hàng 1 col 1. Tôi cũng đã cố gắng không chỉ định bất kỳ câu lệnh SELECT nào trong đường dẫn mã lỗi của tôi nhưng khi kiểm tra giá trị @@ROWCOUNT sau khi gọi tới SP, nó trả về 1 Tôi nghĩ rằng điều này có thể là do @@ROWCOUNT chưa bao giờ được đặt lại từ tuyên bố SELECT trước đó trong SP (trong số EXISTS()). Lời khuyên nào sẽ được đánh giá cao.T-SQL: Cách trả về 0 hàng từ thủ tục lưu sẵn và cách sử dụng XACT_ABORT và TRY/CATCH

Ngoài ra, tôi đã có XACT_ABORT được đặt thành BẬT, nhưng tôi cũng đã sử dụng khối TRY/CATCH để đảm bảo tôi trả về lỗi chính xác "giá trị trả lại" từ quy trình được lưu trữ. Điều này có được không? Nếu có lỗi, việc XACT_ABORT có ghi đè số TRY/CATCH hoặc đường dẫn mã lỗi của tôi vẫn dẫn đến các giá trị trả lại chính xác được trả lại không?

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

Trả lời

12

Để trở về 0 hàng, bạn có thể làm:

SELECT TOP 0 NULL AS MyValue 

Cá nhân, tôi muốn sử dụng một tham số OUTPUT cho sproc này để trả lại ID trở ra thay vì trả lại một resultset - đó chỉ là của tôi sở thích mặc dù. Sau đó, chỉ cần đặt thông số đầu ra đó cho ví dụ: -1 làm mặc định để cho biết không có gì được thực hiện.

+0

Cảm ơn đã phản ứng nhanh chóng! Tôi nhận được một kết quả 0 thiết lập trở lại từ đó :) Nhưng bất kỳ ý tưởng tại sao sau khi 'EXEC MySP' tại sao' @@ ROWCOUNT' = 1? –

+0

'EXEC @ret = MySP; SET @rows = @@ ROWCOUNT; SELECT 'Rows' = @ rows' trả về 1 khi số hàng sau đó !? –

+0

Ah, tôi có nghĩ rằng '@@ ROWCOUNT' chỉ được thay đổi cho các câu lệnh có ảnh hưởng đến các hàng (tức là' INSERT' hoặc 'UPDATE') không? –

1

đây là cách tôi muốn làm điều đó:

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 
Các vấn đề liên quan