2016-05-15 22 views
0

Ich bin neu in Datenbanken und ich versuche, eine gespeicherte Prozedur zu erstellen, die Daten in Tabellen in einer Beziehung viele zu viele einfügt.Wenn ein Teil der Operation fehlschlägt, muss es versuchen, so viel zu erholen wie von der gesamten Operation möglich. Wenn Sie beispielsweise einen Datensatz zu Publishern und Büchern erstellen möchten und die Erstellung des Publishers erfolgreich ist, aber mit dem Buch fehlschlägt, sollte die Erstellung des Buchs, aber nicht des Publishers rückgängig gemacht werden.Insertion transaction- Rollback SQL

Mein Code sieht wie folgt aus:

BEGIN TRY 
     BEGIN TRANSACTION 
     DECLARE @serviciuKey int 
     DECLARE @specializareKey int 


     IF NOT EXISTS (SELECT denumire, moneda, pret FROM Serviciu where [email protected] and [email protected] and [email protected]) 
     BEGIN 
     INSERT INTO Serviciu (denumire, moneda, pret) 
     VALUES (@denumire, @moneda, @pret) 
     END 
     SET @[email protected]@IDENTITY 
     SAVE TRANSACTION savepoint 

     IF NOT EXISTS (SELECT denumire, descriere FROM Specializare where [email protected]_spec AND [email protected]) 
     BEGIN 
     INSERT INTO Specializare(denumire, descriere) 
     VALUES (@denumire_spec, @descriere) 
     END 
     SET @[email protected]@IDENTITY 
     SAVE TRANSACTION savepoint 

     IF NOT EXISTS (SELECT * FROM Specializare_Serviciu where [email protected] and [email protected]) 
     BEGIN 
     INSERT INTO Specializare_Serviciu(cod_specializare, cod_serviciu) 
     VALUES (@specializareKey, @serviciuKey) 
     END 
     SAVE TRANSACTION savepoint 
     COMMIT TRANSACTION 
    END TRY 
    BEGIN CATCH 
     IF @@trancount > 0 ROLLBACK TRANSACTION savepoint 
     DECLARE @msg nvarchar(2048) = error_message() 
     RAISERROR (@msg, 16, 1) 
     RETURN 55555 
    END CATCH 

Wenn ich die Prozedur ausführen, habe ich diesen Fehler: Msg 3931, Ebene 16, Status 1, Prozedur AddData0, Linie 76 Die aktuelle Transaktion kann nicht verpflichtet werden, und kann nicht auf einen Sicherungspunkt zurückgesetzt werden. Rollback die gesamte Transaktion.

Auch wenn ich versuche, einige Daten, die bereits vorhanden sind, einzufügen, wird es mit einer anderen ID eingefügt, was bedeutet, dass IF NOT EXIST-Anweisung nicht funktioniert.

Irgendwelche Hilfe, bitte?

Antwort

0

Versuchen Sie, diese Version:

DECLARE @serviciuKey int 
DECLARE @specializareKey int 

BEGIN TRY 
    BEGIN TRAN 

    IF NOT EXISTS (SELECT denumire, moneda, pret FROM Serviciu where [email protected] and [email protected] and [email protected]) 
    BEGIN 
     INSERT INTO Serviciu (denumire, moneda, pret) 
     VALUES (@denumire, @moneda, @pret) 
    END 

    SET @serviciuKey=scope_identity() 

    IF NOT EXISTS (SELECT denumire, descriere FROM Specializare where [email protected]_spec AND [email protected]) 
    BEGIN 
     INSERT INTO Specializare(denumire, descriere) 
     VALUES (@denumire_spec, @descriere) 
    END 

    SET @specializareKey=scope_identity() 

    IF NOT EXISTS (SELECT * FROM Specializare_Serviciu where [email protected] and [email protected]) 
    BEGIN 
     INSERT INTO Specializare_Serviciu(cod_specializare, cod_serviciu) 
     VALUES (@specializareKey, @serviciuKey) 
    END 

    COMMIT TRAN 
END TRY 
BEGIN CATCH 
    IF @@trancount > 0 
     ROLLBACK TRAN 

    DECLARE @msg nvarchar(2048) = error_message() 
    RAISERROR (@msg, 16, 1) 
    RETURN 55555 
END CATCH 
Verwandte Themen