Avatar billede ghazaleh Nybegynder
17. marts 2006 - 11:39 Der er 15 kommentarer og
1 løsning

Fejl i trigger

Jeg har denne trigger:

CREATE TRIGGER RetKontoSaet ON OrdLn
FOR INSERT,UPDATE
AS
BEGIN
  DECLARE
  @ordrenr INTEGER,
  @kontosaet INTEGER,
  @transtype INTEGER,
  @ordretype INTEGER,
  @gruppe4 INTEGER,
  @kundenr INTEGER

  SELECT @ordrenr=OrdNo
    FROM inserted
  SELECT @ordrenr=OrdNo, @gruppe4=Gr4, @transtype=TrTp, @ordretype=OrdTp, @kundenr=CustNo, @kontosaet=AcSet
    FROM Ord WHERE OrdNo=@ordrenr

  IF (@transtype=1) AND (@ordretype=1)
  BEGIN
    IF (@gruppe4=2) AND (@kontosaet=1)
    BEGIN
      update Ord set AcSet = 101 WHERE Ord.OrdNo = @ordrenr
      update OrdLn set AcSet = 101 WHERE OrdLn.OrdNo = @ordrenr
    END
    IF (@gruppe4=2) AND (@kontosaet=2)
    BEGIN
      update Ord set AcSet = 102 WHERE Ord.OrdNo = @ordrenr
      update OrdLn set AcSet = 102 WHERE OrdLn.OrdNo = @ordrenr
    END
    IF (@gruppe4=2) AND (@kontosaet=3)
    BEGIN
      update Ord set AcSet = 103 WHERE Ord.OrdNo = @ordrenr
      update OrdLn set AcSet = 103 WHERE OrdLn.OrdNo = @ordrenr
    END
    IF (@gruppe4=2) AND (@kontosaet=4)
    BEGIN
      update Ord set AcSet = 104 WHERE Ord.OrdNo = @ordrenr
      update OrdLn set AcSet = 104 WHERE OrdLn.OrdNo = @ordrenr
    END
    IF (@gruppe4=4)
    BEGIN
      update Ord set AcSet = @kundenr WHERE Ord.OrdNo = @ordrenr
      update OrdLn set AcSet = @kundenr WHERE OrdLn.OrdNo = @ordrenr
    END
  END
END

Mit problem er at når jeg har flere linier i OrdLn, så er det kun den første linie der bliver opdateret. Hvordan får jeg den til at opdatere alle linieri OrdLn?
Avatar billede ldanielsen Nybegynder
17. marts 2006 - 11:55 #1
Du siger:

update OrdLn set AcSet = 102 WHERE OrdLn.OrdNo = @ordrenr

Den sætter AcSet = 102 i alle linier hvor OrdLn.OrdNo = @ordrenr. Ikke bare den første, det er 100% sikkert.
Avatar billede ldanielsen Nybegynder
17. marts 2006 - 11:59 #2
Men husk nu at hver gang du updater, så fyres triggeren af igen, så mon det ikke er det der er galt?

Jg ved faktisk ikke hvad ser sker når en trigger går i ring, det skulle da helst give en fejl.

Håber arne_v eller erik_jacobsen ser dette, de ved det garanteret.
Avatar billede Slettet bruger
18. marts 2006 - 06:42 #3
Hvad du ser er en rekursiv trigger og de er some jeg husker det slået fra default i SQL Server. Derfor rammer du kun den første.

Check status med EXEC sp_dboption 'databasenavn', 'recursive triggers'

For at slå til EXEC sp_dboption 'databasenavn', 'recursive triggers', 'true'
For at slå fra EXEC sp_dboption 'databasenavn', 'recursive triggers', 'false'

Du skal nok overveje en anden løsning, for eksempel at lave dine inserts og updates gennem en stored-procedure i stedet for en trigger som bliver rekursiv.
Avatar billede ghazaleh Nybegynder
23. marts 2006 - 15:35 #4
Det tyder på at du har ret Kryptos. Jeg kan ikke helt finde ud af, hvor jeg skal indsætte dine sætninger. Kan jeg slå rekursive triggers til fra Enterprise Manager?
Avatar billede Slettet bruger
23. marts 2006 - 17:01 #5
Tror ikke man kan i EM, men du åbner blot en prompt (Query Analyzer) logget på med sa stående i master databasen og så eksekverer

EXEC sp_dboption 'databasenavn', 'recursive triggers', 'true'

for at slå dem til.
Avatar billede ghazaleh Nybegynder
24. marts 2006 - 11:21 #6
Nu har jeg slået rekursive triggers til. Det løser dog desværre ikke problemet
Avatar billede Slettet bruger
24. marts 2006 - 13:15 #7
Hvad giver følgende ?

SELECT DATABASEPROPERTYEX( 'Database_Navn' , 'IsRecursiveTriggersEnabled' )
Avatar billede ghazaleh Nybegynder
24. marts 2006 - 14:09 #8
den returnerer: Null
Avatar billede Slettet bruger
24. marts 2006 - 17:11 #9
Så er recursive triggers ikke sat korrekt. Den skal returnerer 1.

Noget helt andet, har du overvejet at anvende en Stored-procedure i stedet for - det er jo rent faktisk en rigtig god grund til at det er disabled pr. default. Nemlig at hvis listen bliver stor noget risikerer man et stack overrun.
Avatar billede ghazaleh Nybegynder
27. marts 2006 - 14:08 #10
Du kan nok have ret i at en stored procedure vil være bedre.

Jeg har undgået det fordi, jeg ikke har lavet en stored procedure før, så jeg er lidt i tvivl om hvordan jeg skal lave det om til en stored procedure.

Er det nemt at gøre?
Avatar billede Slettet bruger
27. marts 2006 - 14:34 #11
Der er ikke ret meget forskel på en trigger og en stored procedure ud over hvem der starter den og hvordan den kaldes. Det er T-SQL i begge tilfælge.
Avatar billede ghazaleh Nybegynder
30. marts 2006 - 11:55 #12
Ja jeg har flyttet min kode over i en stored procedure. Men nu har jeg lidt svært ved at finde ud af hvordan jeg så får den aktiveret, når der bliver indsat en linie i min tabel ordln
Avatar billede ghazaleh Nybegynder
30. marts 2006 - 12:02 #13
hehe okay det var ikke så svært. Jeg lavede selvfølgelig bare en trigger, der agde EXECUTE

Men nu har jeg så det problem at i min trigger der havde jeg linien:

SELECT @ordrenr=OrdNo FROM inserted

Det kan den ikke finde ud af i en stored procedure, hvordan får jeg fat i mit ordrenummer i den stored procedure?
Avatar billede Slettet bruger
30. marts 2006 - 12:54 #14
Hvis det skal give nogen mening skal du ændre dine inserts og deletes til kald til stored-procedures. Det nytter ikke blot at flytte koden i triggeren til en stored-procedure, så har du præcist sammen problem blot er den indirekte rekursion.
Avatar billede ghazaleh Nybegynder
03. april 2006 - 13:31 #15
Nu tror jeg endelig, at jeg forstod hvorfor min trigger var rekursiv, så nu har jeg lavet den om, så jeg undgår at dette.

Men i min nye trigger bliver jeg nød til at regne fx:

@kontosaet = @kontosaet * 100

Hvordan er syntaksen for det i en trigger?
Avatar billede ghazaleh Nybegynder
03. april 2006 - 14:10 #16
Glem det. det var mig der var dum igen :-)

Du har vist efterhånden fået svaret fuldt ud på mit spørgsmål ;-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester