Procedura - pomoc w zrozumieniu działania

0

Witam,
Poproszę o pomoc, aby zrozumieć dlaczego tak się dzieje, co robię źle.
Procedury poniżej mają pomóc zobrazować problem.

Chciałbym po zakończeniu procedury uzyskać jej wynik:
0 - poszła
1 - błąd
Wiem, że standardowo procedura nie zwraca wartości :-)
I szukam rozwiązania.

Na początku próbowałem to osiągnąć stosując: @product_count INT OUTPUT zgodnie z przykładem poniżej.
Ale gdy procedura "nie przeszła - ROLLBACK" to nie zwracała wartości.
Wartość zawsze była zwracana gdy procedura była wykonana bez błędów.

Przy stosowaniu @product_count INT OUTPUT - działało pod warunkiem gdy nie było włączone: TRY / CATCH
Bazowałem na tym przykładzie:

    CREATE OR ALTER PROCEDURE [dbo].[GetCustomerEmail]
    (@FirstName AS varchar(100),
    @CountRecords int OUTPUT
    )
    AS
    BEGIN
     SELECT FirstName, MiddleName, Lastname, EmailAddress 
   FROM [SalesLT].[Customer] 
     WHERE FirstName = @FirstName
    
    SELECT @CountRecords = @@ROWCOUNT;
  END
  GO

Wymyśliłem wiec takie rozwiązanie... działa przy TRY / CATCH.

CREATE PROCEDURE dbo.TEST
AS
BEGIN TRY
 BEGIN TRANSACTION
 
  INSERT INTO table1 (Nazwa)
  VALUES ('121111');  -- Pole tabeli INT

  If @@ROWCOUNT <> 0
   begin
   Select 0 as StatusWyjscia
  end;
  
 COMMIT TRANSACTION
END TRY

BEGIN CATCH  
If @@ROWCOUNT = 0
  begin
  Select 1 as StatusWyjscia
  end;
END CATCH

Baza SQL Server Express 2019

2

Zerknij co można z CATCH zwrócić
https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-ver16#retrieving-error-information

Przetestuj też RETURN jeśli chcesz koniecznie mieć 1 na błąd

0

Dzięki, poszło: SELECT IsNull(ERROR_NUMBER(),0) AS ErrorNumber;
Parametr wraca do SSRS i odpowiednio wyświetla informację.

Tylko jak to się ma do teorii: @zmienna int OUTPUT

CREATE PROCEDURE dbo.PartiaZmien
@PLU varchar (6),
@PartiaObecna varchar (7),
@PartiaNowa varchar (7),
@DataWazenia date
AS
BEGIN TRY
  BEGIN TRANSACTION
  
  UPDATE BIZERBA_BRAIN2_Result.dbo.PackageRecord SET
  BIZERBA_BRAIN2_Result.dbo.PackageRecord.BatchNumber = @PartiaNowa
  WHERE
  BIZERBA_BRAIN2_Result.dbo.PackageRecord.ArticleNumber = @PLU AND
  BIZERBA_BRAIN2_Result.dbo.PackageRecord.BatchNumber = @PartiaObecna AND
  (CONVERT(DATE, BIZERBA_BRAIN2_Result.dbo.PackageRecord.Timestamp)) = @DataWazenia;
    
  INSERT INTO dbo.Procedure_Success (Nazwa)
  SELECT
  OBJECT_NAME(@@PROCID);
  
  DELETE dbo.Procedure_Success
  WHERE
  dbo.Procedure_Success.Data <=(DATEADD(day,-366,Convert(DATE,GETDATE())));
  
  COMMIT TRANSACTION
  PRINT 'REKORDY ZAKTUALIZOWANE';
  SELECT IsNull(ERROR_NUMBER(),0) AS ErrorNumber;
END TRY

BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
  -- Te linie służą do rejestracji błedów procedur.
  INSERT INTO dbo.PROCEDURE_ERROR (ErrorNumber, ErrorSeverity, ErrorState, ErrorProcedure, ErrorLine, ErrorMessage)
  SELECT
   ERROR_NUMBER() AS ErrorNumber,
   ERROR_SEVERITY() AS ErrorSeverity,
   ERROR_STATE() AS ErrorState,
   ERROR_PROCEDURE() AS ErrorProcedure,
   ERROR_LINE() AS ErrorLine,
   ERROR_MESSAGE() AS ErrorMessage;
  PRINT 'REKORDY NIE ZAKTUALIZOWANE - SPRAWDŹ';

   SELECT
   CASE WHEN IsNull(ERROR_NUMBER(),0) <> 0 THEN 1
   ELSE 0 End AS ErrorNumber;
   
END CATCH
0

Generalnie w T-SQLu procedura może zwracać dane na kilka sposobów.
Jednym z nich jest SELECT (jak to zrobiłeś na końcu) wyciągający zestaw danych. Ale nie zawsze chcesz dostać zestaw danych. Czasem potrzeba Ci pojedynczej wartości, np. kod błędu (wtedy najłatwiej skorzystać z RETURN), lub kilku wartości (wtedy przyda się właśnie OUTPUT), by przypisać je do zmiennych. Co ważne, można wykorzystać wszystkie metody jednocześnie.

Tutaj masz przykład procedury na szybko:

CREATE PROCEDURE dbo.test (
	@num INT
	,@double INT OUTPUT
)
AS
BEGIN
	DECLARE @triple INT
	SET @double = @num*2
	SET @triple = @num*3
	RETURN @triple
END

I wywołanie :

DECLARE @jakasLiczba INT
        ,@razyDwa INT
		,@razyTrzy INT
  
SET @jakasLiczba = 43

EXEC @razyTrzy = dbo.test @jakasLiczba, @razyDwa OUTPUT

SELECT @razyDwa, @razyTrzy
0

Dziękuję,
Muszę teraz "powalczyć" w temacie aby to bardziej ogarnąć. Ale jakaś podstawa do rozpoczęcia już jest.

1 użytkowników online, w tym zalogowanych: 0, gości: 1