Autor Téma: Trigger BEFORE DELETE - vytvorenie  (Přečteno 2556 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5976
  • Karma: 43
    • Verze Delphi: W10 + D11
Trigger BEFORE DELETE - vytvorenie
« kdy: 06-07-2016, 13:46:59 »

Pokúšam sa vytvoriť spúšť Before Delete na zabránenie vymazania niektorých záznamov. Nedarí sa mi
Kód: [Vybrat]
CREATE TRIGGER NUMDOCDEFAULTS_BD FOR NUMDOCDEFAULTS
ACTIVE BEFORE DELETE
POSITION 0
AS
BEGIN
  IF OLD.IDNUMDOCDEFAULTS <= 20 THEN /* Zákaz vymazania záznamov */
  BEGIN
    RAISERROR ('Záznam nemôže byť vymazaný - transaction aborted.', 16, 1) /* */
    ROLLBACK TRANSACTION
  END;
END;
Precompiler Error: Syntax error - OLD.
Bez OLD
Precompiler Error: Syntax error - IDNUMDOCDEFAULTS.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3287
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #1 kdy: 06-07-2016, 14:53:22 »
  IF OLD.IDNUMDOCDEFAULTS <= 20 THEN /* Zákaz vymazania záznamov */
To vypada na nejake indukovane chyby. Rekl bych, ze primarni pricinou jsou chybejici zavorky kolem podmineneho vyrazu (jako v C-like jazykach), tj. spravne ma byt
Kód: SQL [Vybrat]
  1. IF (OLD.IDNUMDOCDEFAULTS <= 20) THEN /* Zákaz vymazania záznamov */

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5976
  • Karma: 43
    • Verze Delphi: W10 + D11
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #2 kdy: 06-07-2016, 14:58:18 »
Máš pravdu. Ale vyskočila chyba na riadku ROLLBACK TRANSACTION
Viem,  že tam môžem volať EXCEPTION. Radšej by som ostal pri zrušení transakcie.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3287
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #3 kdy: 06-07-2016, 15:12:26 »
Máš pravdu. Ale vyskočila chyba na riadku ROLLBACK TRANSACTION
Viem,  že tam môžem volať EXCEPTION. Radšej by som ostal pri zrušení transakcie.
To je chybna uvaha - transakce je rizena zvnejsku a ten trigger by do ni nemel zasahovat, protoze pracuje v jejim kontextu. Raisnuti exception v triggeru je spravne reseni. Na urovni klienta odchytit, zjistit co se stalo, tam teprve rollnout back, zalogovat a oznamit BFU

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5976
  • Karma: 43
    • Verze Delphi: W10 + D11
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #4 kdy: 06-07-2016, 15:17:53 »
Na klientovi to mám ošetrené samostatne.
Ja chcem ešte poistku aj v DB. Ak sa napr. budem vŕtať priamo v DB, aby som si nevymazal čo nemám. Samozrejme, že aj z klienta - nie je problém urobiť chybu.
Ďakujem.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3287
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #5 kdy: 06-07-2016, 15:28:37 »
Ja chcem ešte poistku aj v DB. Ak sa napr. budem vŕtať priamo v DB, aby som si nevymazal čo nemám.
Kdyz raisnes exception, tak ti to snad nastroj, kterym se v DB hrabes, rekne a zadne zmeny neudela
(nepamatuju se, co se stane s raisnutou transakci, zda by sla teoreticky commitnout, mam dojem, ze ne)

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1558
  • Karma: 37
    • Pepak.net
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #6 kdy: 07-07-2016, 07:16:04 »
Kód: SQL [Vybrat]
  1.   IF OLD.IDNUMDOCDEFAULTS <= 20 THEN /* Zákaz vymazania záznamov */
Precompiler Error: Syntax error - OLD.
Bez OLD
Precompiler Error: Syntax error - IDNUMDOCDEFAULTS.
Podmínka IFu musí být uzavřena v závorkách.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1558
  • Karma: 37
    • Pepak.net
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #7 kdy: 07-07-2016, 07:25:16 »
(nepamatuju se, co se stane s raisnutou transakci, zda by sla teoreticky commitnout, mam dojem, ze ne)
Udělal jsem si teď rychlý test ve FB2.5 a commit projde. Taky moc nevidím důvod, proč by neměl - pokud si v reakci na výjimku explicitně vyžádám COMMIT, tak by mi to IMHO databáze měla umožnit. Tedy, v tom případě, co jsem testoval - že zavolám UPDATE pro změnu tabulky a potom vyvolám výjimku přes EXCEPTION. Nezkoušel jsem, co to udělá s výjimkou v BEFORE triggeru, ale z logiky věci vyplývá, že ten se provede ještě předtím, než proběhne zápis nových hodnot do tabulky, takže když v něm dojde k výjimce, tak se celý zápis zruší.
« Poslední změna: 07-07-2016, 07:27:29 od pepak »

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1558
  • Karma: 37
    • Pepak.net
Re:Trigger BEFORE DELETE - vytvorenie
« Odpověď #8 kdy: 07-07-2016, 07:30:53 »
No jasně. BEFORE trigger samozřejmě zruší celý statement, pokud dojde k výjimce. Ale jenom ten chybující statement, ne ty předchozí, takže ty odcommitovat jde.