UPDATE: opgelost middels een andere opzet, zie laatste post.
Voor een project ben ik bezig om de database op te zetten. Het gaat om een soort app. In deze app zijn verschillende zaken waarop gereageerd kan gaan worden. Denk aan commentaar op muziektracks, commentaar op muziekalbums, commentaar op tweets (etecetra).
Nu lijkt het mij een goede zaak om 1 algemene comments tabel op te zetten voor al deze zaken. Alleen moet deze tabel wel relaties hebben met de verschillende andere tabellen. Ergens op het internet las ik een elegante manier om dit op te lossen, met een soort tussentabel. Intussen heb ik dat als volgt gemaakt:

Elke tabel waarop gereageerd kan worden (in dit geval tblTrack en tblAlbum), heeft een relatie met de tabel tblCommentRelation middels een Foreign Key (FK_CommentRelationID). De tussentabel (tblCommentRelation) heeft weer een directe relatie met tblComment. Het is de bedoeling dat er een nieuwe row wordt ge-insert bij tblCommentRelation voor elke insert in tblTrack en tblAlbum. Zodra iemand ergens daadwerkelijk op reageert, komt er een post bij in de tabel tblComment.
Dit lijkt mij de beste oplossing, hierbij is er immers sprake van echte relaties. Mocht iemand overigens een betere weten, dan hoor ik het graag...
Maar verder:
Middels trigger logica wil ik er dus voor zorgen dat er een nieuwe row in tblCommentRelation wordt gemaakt bij elke insert in tblAlbum of tblTrack.
Om de referential integrity te waarborgen, mogen de foreign keys in tblAlbum en tblTrack niet NULL zijn. Bij een insert in bijvoorbeeld tblTrack voer ik alleen de TrackName in. De triggercode moet vervolgens de row in tblCommentRelation aanmaken, de PK daarna ophalen en vervolgens deze vervolgens samen met mijn TrackName inserten...
Ik vind het moeilijk helder te omschrijven, hopelijk is het tot dusver duidelijk...
Volgens mij is de enige mogelijke oplossing voor dit probleem gebruik te maken van een INSTEAD OF insert. Probleem is namelijk dat de trigger nooit zal vuren als ik een FOR insert gebruik omdat ik geen NULL values mag inserten. De INSTEAD OF trigger moet deze NULL waarde dus gaan vullen met de PK uit tblCommentRelation, en daarna de werkelijke insert gaan doen.
Intussen heb ik deze code geschreven:
Verder kom ik helaas niet. Ik mag de virtual INSERTED table niet wijzigen. Ik ga nog tientallen velden toevoegen, en wil niet bij elk nieuw veld de trigger moeten aanpassen. Dus indien mogelijk wil ik niet in code een table variable gaan aanmaken met velden (want deze zal ik dan dus bij elke wijziging moeten aanpassen). Bovendien ben ik bang dat deze code sowieso op zijn bek gaat bij een batch insert... Heb vele fora bezocht, maar heb niet een oplossing kunnen vinden. Kan iemand mij verder helpen?
Voor een project ben ik bezig om de database op te zetten. Het gaat om een soort app. In deze app zijn verschillende zaken waarop gereageerd kan gaan worden. Denk aan commentaar op muziektracks, commentaar op muziekalbums, commentaar op tweets (etecetra).
Nu lijkt het mij een goede zaak om 1 algemene comments tabel op te zetten voor al deze zaken. Alleen moet deze tabel wel relaties hebben met de verschillende andere tabellen. Ergens op het internet las ik een elegante manier om dit op te lossen, met een soort tussentabel. Intussen heb ik dat als volgt gemaakt:

Elke tabel waarop gereageerd kan worden (in dit geval tblTrack en tblAlbum), heeft een relatie met de tabel tblCommentRelation middels een Foreign Key (FK_CommentRelationID). De tussentabel (tblCommentRelation) heeft weer een directe relatie met tblComment. Het is de bedoeling dat er een nieuwe row wordt ge-insert bij tblCommentRelation voor elke insert in tblTrack en tblAlbum. Zodra iemand ergens daadwerkelijk op reageert, komt er een post bij in de tabel tblComment.
Dit lijkt mij de beste oplossing, hierbij is er immers sprake van echte relaties. Mocht iemand overigens een betere weten, dan hoor ik het graag...
Maar verder:
Middels trigger logica wil ik er dus voor zorgen dat er een nieuwe row in tblCommentRelation wordt gemaakt bij elke insert in tblAlbum of tblTrack.
Om de referential integrity te waarborgen, mogen de foreign keys in tblAlbum en tblTrack niet NULL zijn. Bij een insert in bijvoorbeeld tblTrack voer ik alleen de TrackName in. De triggercode moet vervolgens de row in tblCommentRelation aanmaken, de PK daarna ophalen en vervolgens deze vervolgens samen met mijn TrackName inserten...
Ik vind het moeilijk helder te omschrijven, hopelijk is het tot dusver duidelijk...
Volgens mij is de enige mogelijke oplossing voor dit probleem gebruik te maken van een INSTEAD OF insert. Probleem is namelijk dat de trigger nooit zal vuren als ik een FOR insert gebruik omdat ik geen NULL values mag inserten. De INSTEAD OF trigger moet deze NULL waarde dus gaan vullen met de PK uit tblCommentRelation, en daarna de werkelijke insert gaan doen.
Intussen heb ik deze code geschreven:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| USE [TEST] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER .[dbo].[BI_tblTrack_CommentRelation] ON [dbo].[tblTrack] INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON; DECLARE @int int; Insert into tblCommentRelation (CommentRelationSource) VALUES ('tblTrack'); SET @int = Scope_identity() PRINT @int; --inderdaad, de variable print heeft nu de scope_identity waarde... END |
Verder kom ik helaas niet. Ik mag de virtual INSERTED table niet wijzigen. Ik ga nog tientallen velden toevoegen, en wil niet bij elk nieuw veld de trigger moeten aanpassen. Dus indien mogelijk wil ik niet in code een table variable gaan aanmaken met velden (want deze zal ik dan dus bij elke wijziging moeten aanpassen). Bovendien ben ik bang dat deze code sowieso op zijn bek gaat bij een batch insert... Heb vele fora bezocht, maar heb niet een oplossing kunnen vinden. Kan iemand mij verder helpen?