2010-08-18 11 views
7

Piszę procedurę przechowywaną i chcę zwrócić 0 rekordów, gdy coś się nie powiedzie. Nie mogę wymyślić, jak po prostu zwrócić 0 wierszy? Użyłem SELECT NULL, ale to zwraca 1 wiersz z NULL w wierszu 1 kolumnie 1. Próbowałem również nie określając żadnych instrukcji SELECT w mojej ścieżce kodu błędu, ale podczas testowania wartości @@ROWCOUNT po wywołaniu do SP, zwrócił 1 Myślę, że może tak być dlatego, że @@ROWCOUNT nigdy nie został zresetowany z wcześniejszego oświadczenia w SP (w EXISTS()). Każda rada byłaby doceniona.T-SQL: Jak zwrócić 0 wierszy z procedury przechowywanej i jak używać XACT_ABORT i TRY/CATCH

Mam również XACT_ABORT ustawiony na WŁĄCZONY, ale użyłem również bloku TRY/CATCH, aby upewnić się, że zwracam poprawny błąd "zwracaną wartość" z procedury przechowywanej. Czy to w porządku? Jeśli wystąpi błąd, czy XACT_ABORT zastąpi TRY/CATCH lub czy ścieżka mojego kodu błędu nadal będzie prowadzić do zwracania poprawnych wartości zwracanych?

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

Odpowiedz

12

Aby powrócić 0 wierszy, można zrobić:

SELECT TOP 0 NULL AS MyValue 

Osobiście używam parametru wyjściowego dla tego sproc powrócić identyfikator powrotem zamiast wrócić zestaw wyników - to tylko moja preferencje chociaż. Następnie po prostu ustaw ten parametr wyjściowy na np. -1 jako domyślny, aby wskazać, że nic nie zostało zrobione.

+0

Dzięki za szybką odpowiedź! Z tego powodu otrzymuję zerowy wynik :) Ale jakikolwiek pomysł, dlaczego po "EXEC MySP" dlaczego '@@ ROWCOUNT' = 1? –

+0

'EXEC @ret = MySP; SET @rows = @@ ROWCOUNT; WYBIERZ "Wiersze" = @ wiersze' zwraca 1, a następnie liczba wierszy !? –

+0

Ach, mam rację, myśląc, że '@@ ROWCOUNT' jest zmieniany tylko w przypadku instrukcji dotyczących wierszy (np.' INSERT' lub 'UPDATE')? –

1

to jak bym go zrobić:

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 
Powiązane problemy