Avatar billede hulla Novice
26. februar 2003 - 15:12 Der er 20 kommentarer og
1 løsning

Triggers

Jeg har spurgt før, men uden 100 % held..

Jeg har 2 tabeller: Main og ItemsForSale.

I Main har jeg et felt der hedder ForSale som kan være enten 0 eller 1.
I ItemsForSale har jeg oplysniner såsom pris og reservation og den slags.
De to tabeller har begge et felt der hedder IDNumber, og de numre "hænger sammen" så der er tale om det samme item.

Jeg vil gerne have en trigger der fyres af hver gang ForSale i Main opdateres, og som tester på om den herefter er 1 eller 0.
Er den 0 skal dens "ven" i ItemsForSale slettes helt,..¨

hvordan gøres det ????
Avatar billede techhouse Nybegynder
26. februar 2003 - 16:46 #1
Sådan skal din trigger laves...
Er testet på SQL2000 og virker!!! Både når du ændre en eller MANGE records
/Thomas

CREATE TRIGGER ut_main ON [dbo].[Main]
FOR UPDATE
AS
    SET NOCOUNT on

    Declare @@IDnumber as Integer
    Declare @@ForSale as integer

    IF UPDATE(ForSale)
    IF @@ROWCOUNT = 1
    BEGIN
        SELECT @@IDnumber=IDnumber, @@ForSale=ForSale FROM inserted
        if @@ForSale=0 Delete from ItemsForSale where IDnumber=@@IDnumber
    END ELSE
    BEGIN
        DECLARE ut_main_cursor CURSOR FOR
        SELECT IDnumber, ForSale FROM inserted

        OPEN ut_main_cursor

        -- hent første
        FETCH NEXT FROM ut_main_cursor into @@IDnumber, @@ForSale

        -- Check @@FETCH_STATUS
        WHILE @@FETCH_STATUS = 0
        BEGIN
            if @@ForSale=0 Delete from ItemsForSale where IDnumber=@@IDnumber
            FETCH NEXT FROM ut_main_cursor into @@IDnumber, @@ForSale
        END

        CLOSE ut_main_cursor
        DEALLOCATE ut_main_cursor

    END
Avatar billede janus_007 Nybegynder
26. februar 2003 - 22:40 #2
uhauha da, sådan noget må man aldrig gøre, en cursor i en trigger... Meget meget skamfuldt!

Det eneste der skal til for opfylde tullas behov er:

CREATE TRIGGER delForSale ON dbo.Main
FOR UPDATE
AS
IF NOT UPDATE(ForSale)
RETURN
DELETE ItemsForSale WHERE id = (SELECT id FROM INSERTED)

---------

tulla, tag det som en fortsættelse af den anden tråd. Jeg vil ikke have point, men lov mig at du aldrig bruger en cursor i en trigger medmindre det er eneste udvej (og det er det meget sjældent).
Avatar billede janus_007 Nybegynder
26. februar 2003 - 22:40 #3
tulla = hulla ... *LOL*
Avatar billede janus_007 Nybegynder
26. februar 2003 - 22:44 #4
hmm, hvis den sføli kun skal slette når forsale bliver sat til 0, da:

CREATE TRIGGER delForSale ON dbo.Main
FOR UPDATE
AS
IF NOT UPDATE(ForSale)
RETURN
DECLARE @id INT, @fs INT
SELECT @id = id, @fs = ForSale FROM INSERTED
IF @fs = 0
DELETE ItemsForSale WHERE id = @id
Avatar billede techhouse Nybegynder
27. februar 2003 - 06:33 #5
Janus_007 du har helt ret i at det ikke er en god ide at bruge cursor i en trigger, derfor er koden lavet så den checkker @@rowcount og kun benytter cursoren HVIS man fx opdaterer FLERE rækker. Din løsning virker IKKE på flere rækker (fx update forsale=0 where kunde='janus_007' ) men kun på EN, men vi man aldring kommer i den sitiuation er dette jo ikke noget problem!

/Thomas
Avatar billede hulla Novice
27. februar 2003 - 08:45 #6
Det ser rigtigt ud,.. men der er lige et lille problem, mit id er ikke en int, men en VarChar, og det er den ganske enkelt nødt til at være. Jeg bruger så selvfølgelig varchar i triggeren,.meeen det virker ikke, ved en af jer noget om det ?
Avatar billede hulla Novice
27. februar 2003 - 08:56 #7
Har jeg ret i at INSERTED tager fat i en række der lige er sat ind ??
Avatar billede hulla Novice
27. februar 2003 - 09:32 #8
sådan her ser min trigger ud nu:

CREATE TRIGGER delForSale ON dbo.Main
FOR UPDATE
AS
IF UPDATE(ForSale)
DECLARE @id varchar, @fs int
SELECT @id = IDnumber, @fs = ForSale FROM INSERTED
IF @fs = 0
DELETE dbo.ItemsForSale WHERE dbo.ItemsForSale.IDnumber = @id

Men den sletter ingenting, og jeg får ingen fejlmeddelelser af nogen art.
Avatar billede hulla Novice
27. februar 2003 - 10:05 #9
Fjerner jeg WHERE klausulen sletter den det hele som forventet, så det virker som om INSERTED ikke er den rigtige,.eller ???
Avatar billede techhouse Nybegynder
27. februar 2003 - 10:33 #10
Du mangler en BEGIN END og så synes jeg det vil være en rigtig god ide af sætte størrelse på din varchar
/Thomas

CREATE TRIGGER delForSale ON dbo.Main
FOR UPDATE
AS
IF UPDATE(ForSale)
BEGIN
  DECLARE @id varchar(10), @fs int
  SELECT @id = IDnumber, @fs = ForSale FROM INSERTED
  IF (@fs = 0) DELETE FROM dbo.ItemsForSale WHERE dbo.ItemsForSale.IDnumber = @id
END
Avatar billede hulla Novice
27. februar 2003 - 11:15 #11
Det virker ikke,...

Når jeg fyrer denne her af i min Enterprise manager:

UPDATE    Main
SET      ForSale = 0

sætter den alle ForSale = 0, men sletter ikke noget i ItemsForSale.
Jeg har også prøvet med curser metoden, men den sletter ingenting
Avatar billede techhouse Nybegynder
27. februar 2003 - 11:23 #12
Det er fordi du ikke benytte cursor som i mit eksample
Du skal benytte cursor hvis du ønsker at lave ændringer på mere end en record
Avatar billede hulla Novice
27. februar 2003 - 11:29 #13
Jeg har også prøvet med curser metoden, men den sletter ingenting
Avatar billede nop Nybegynder
27. februar 2003 - 11:37 #14
Update triggere er i sig selv ikke til at opdatere med, de er kun til at få udført et event som fx bremser updaten eller sørger for at der opdateres i andre tabeller.
Update skal ses som, delete + insert.
Avatar billede hulla Novice
27. februar 2003 - 11:41 #15
Jo så virker det techhouse,.. tak for hjælpen, det blev dit jeg brugte :o)
Avatar billede janus_007 Nybegynder
27. februar 2003 - 17:59 #16
Jeg gentager lige igen... Lad være med at bruge cursor i en trigger! -

Ved updatering af flere værdier, laves blot en SELECT ala...
DELETE ItemsForSale WHERE id IN (SELECT id FROM Main WHERE ForSale = 0)

eller måske, hvis man hellere er ligeglad med 0 eller 1 så bare:
DELETE ItemsForSale WHERE id IN (SELECT id FROM INSERTED)

techhouse, få styr på din sql.... og undgå at bruge cursor løsninger!!
og forøvrigt techhouse, man behøver ikke en BEGIN END ved 1 linjes statement, en varchar skal altid sættes til en størrelse, så det er ikke bare en god idé, det er et krav!!
Avatar billede techhouse Nybegynder
27. februar 2003 - 18:02 #17
Så lærte jeg også noget.
Takker
Avatar billede techhouse Nybegynder
27. februar 2003 - 18:11 #18
CREATE TRIGGER ut_main ON [dbo].[Main]
FOR UPDATE
AS
SET NOCOUNT on

    IF UPDATE(ForSale)
    Delete from ItemsForSale where IDnumber in
        (select IDnumber from inserted where ForSale=0)
Avatar billede techhouse Nybegynder
27. februar 2003 - 18:14 #19
Efter janus_007 gode indlæg og ide kan triggeren ændres til overnævnte
Jeg har til tilført "where ForSale=0" således at vi ikke får formeget access til SQLen.

/Thomas
Avatar billede janus_007 Nybegynder
27. februar 2003 - 18:24 #20
jamen så lærte jeg også noget, var ikke klar over man kunne sætte en where-clause på inserted!!

Utroligt hvad man kan udrette i fællesskab :O)

Hygge og god dag/ aften....
Avatar billede techhouse Nybegynder
27. februar 2003 - 18:30 #21
jeps og det samme til dig...
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