Vraag & Antwoord

Webprogrammeren & scripting

MS SQL: Triggers

Anoniem
None
9 antwoorden
  • Ik weet niet of 'webprogrammeren' wel helemaal het goed rubriekje is, maar aangezien er geen 'SQL' rubriek is en ik toch met een site bezig ben..

    In access was het zo dat je de boel kon instellen dat, wanneer je een record verwijderd of update, de bijbehorende records ook automatisch verwijderd/geupdate werden.
    In MS SQL werkt dit gloof ik niet zo. Vandaar dat ik dit met triggers wil oplossen.

    Is dit de goede manier, of moet dit geheel anders?

    ff een voorbeeldje erbij:

    Ik heb twee tabellen.
    'tblOrder' met algemene gegevens over de order en 'tblOrderDetails' met alle producten die tot deze order behoren..

    Als ik een order verwijderen uit tblOrder dan wil ik natuurlijk dat alle (vanaf dan 'orhpaned' records ook verwijderd worden.

    Hoe ziet in zo'n geval een trigger eruit?

    bvd,

    Elja
  • Ik heb inmiddels de trigger volgens mij aardig bedacht:

    [code:1:731b64f5dd]
    CREATE TRIGGER tr_DeleteOrderItems ON SQLstudentdesign.tblOrder
    FOR DELETE
    AS
    /*
    * CASCADE DELETES TO 'tblOrderItems'
    */
    DELETE tblOrderItems
    FROM deleted, tblOrderItems
    WHERE deleted.OrderNr = tblOrderItems.OrderNr
    [/code:1:731b64f5dd]

    Met deze trigger kreeg ik dus echter een fout omdat de 'relations' (zoals ook bij access) er wel een beetje inzitten. Alleen die werken dus niet wanneer je een record (bv. in tblOrder) delete.

    Dit is zoals ik het nu werkend heb:

    check existing data on creation
    enforce relationsship for replication
    enforce relationship for INSERTS and UPDATEs

    1 staat uit
    2 staat aan
    3 staat uit (AAN geeft foutmelding bij deleten record in parent table)

    Weet iemand wat hier nu de fatsoenlijke oplossing voor is ?
  • Hebben we het hier over mssql 7 of 2000?
    In 2000 kan je cascading als eigenschap van de tabel definieren.
    bijv:
    ON DELETE CASCADE

    In sql7 zal je inderdaad zelf aan de gang moeten met triggers of deze deletes in een sproc zetten.

    btw. de combinatie van constraints en triggers kan op dit punt niet aangezien een constraint violation eerst zal ingrijpen voor de trigger in werking treedt (tenzij je de check natuurlijk uitzet).

    Meer info:
    http://www.sqlmag.com/Articles/Index.cfm?ArticleID=8687&pg=1
    http://support.microsoft.com/default.aspx?scid=kb;EN-US;q142480
  • Thx Annie..

    Het is me zo wat duidelijker geworden..
    De provider gebruikt ms Sql 7, dus daar moeten we het mee doen..

    Grtz Elja
  • btw. mijn voorkeur heeft de aanpak met sprocs. Al was het maar om het feit dat je over het algemeen zelf in de hand wil houden hoe de deletes worden uitgevoerd op de database.
    En het is imho wat makkelijker te onderhouden en wat duidelijker (maar dat is natuurlijk wel persoonlijk).
  • Nog even een vraagje.
    Zou je met gebruik van triggers voor Update en Delete nu alle onderstaande vinkjes uitzetten?

    check existing data on creation
    enforce relationsship for replication
    enforce relationship for INSERTS and UPDATEs

    Waar dienen deze precies voor?

    Grtz Elja
  • [b:940d2f5eaa]check existing data on creation [/b:940d2f5eaa]
    Controleer bestaande data in tabel bij de aanleg van de constraint. Dus als er data in de tabellen voorkomt die in strijd is met de constraint dan krijg je een foutmelding en kan de constraint niet aangelegd worden.

    [b:940d2f5eaa]enforce relationsship for replication[/b:940d2f5eaa]
    Check de referentiele integriteit ook als de data gerepliceerd wordt naar een andere database. In 99% van de gevallen heb je daar eigenlijk niets mee te maken.

    [b:940d2f5eaa]enforce relationship for INSERTS and UPDATEs[/b:940d2f5eaa]
    Betekend dat bij inserts, updates en deletes de referentiele integriteit wordt afgedwondgen. Het is dus ook mogelijk om een foreign key relatie aan te leggen zonder dat je daar een constraint aan verbindt.
  • Beste Annie,

    Bedankt voor je duidelijke uitleg.

    Ik heb nu per relatie 2 triggers aangemaakt.
    een trigger die per relatie de bijbehorende childtable records verwijdert als er een record uit de parenttable wordt verwijdert. en een trigger die ze update.

    Als ik het goed begrijp kan dit dit volgens jouw bovenstaande uitleg ook dmv die vinkjes. Ik had dit in eerste instantie geprobeerd, maar dat werkte niet.
    Klopt dat, en moet ik inderdaad met deze triggers werken, of moeten die standaard triggers weg en moet ik die vinkjes goed aanzetten?

    Grtz Elja
  • Ja en Nee :wink:
    In sql2000 kan je het met de vinkjes regelen (daar krijg je er namelijk nog een paar opties bij voor het "cascaden";) en hoef je in principe geen gebruik te maken van trigger of sproc constructies.

    In sql7 [b:ad564d10c4]moet[/b:ad564d10c4] je juist de vinkjes [b:ad564d10c4]uitzetten[/b:ad564d10c4] om er voor te zorgen dat de foreign key relatie niet afgedwongen wordt als je gebruik wil maken van de triggers.
    Dus eigenlijk hebben de relaties op dat moment geen zin, behalve dan dat je diagram er duidelijker uitziet.

    Maar de methode met de triggers zorgt er natuurlijk wel voor dat je referentiele integriteit in gevaar kan komen. Mijn voorkeur heeft een methode met sprocs. De constraints kunnen dan gewoon intact blijven en op het moment dat een delete moet worden uitgevoerd gebeurt dit via een sproc.
    Simpel voorbeeldje
    [code:1:ad564d10c4]
    create proc spDeleteIets
    @id int
    as
    – eerst eventuele childs deleten
    delete from childTable where fk_id=@id
    – daarna pas de eigenlijke row deleten
    delete from mainTable where pk_id=@id
    go
    [/code:1:ad564d10c4]

    [ Dit Bericht is bewerkt door: Annie op 2002-02-05 14:49 ]

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.