Toon posts:

Ms SQL trigger loopt vast bij insert

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben een trigger aan het schrijven die van een tabel alle veldnamen ophaalt en deze dan in een cursor overloopt en vergelijkt met de oude en nieuwe waarde bij het uitvoeren van een insert of update op deze tabel.

Probleem is nu dat deze vastloopt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE TRIGGER Update_Products
 ON [dbo].[PRODUCTS] 
FOR INSERT,UPDATE
AS
create table #MyInternalList (
list_item    varchar(300) not null)

insert #MyInternalList
exec ( "SELECT top 1     syscolumns.name AS column_name
FROM         sysobjects INNER JOIN
                      syscolumns ON sysobjects.id = syscolumns.id INNER JOIN
                      systypes ON syscolumns.xtype = systypes.xtype
WHERE     (sysobjects.xtype = 'U') AND (sysobjects.name = 'PRODUCTS')
ORDER BY sysobjects.name, syscolumns.colid" )

DECLARE @waarde as varchar(100)
DECLARE @waarde_oud VARCHAR(5000)
DECLARE @waarde_nieuw VARCHAR(5000)
DECLARE @gebruiker VARCHAR(150)
DECLARE products_cursor CURSOR FOR 
    SELECT * FROM #MyInternalList
    OPEN products_cursor
    FETCH products_cursor INTO @waarde
    WHILE @@fetch_status = 0
    BEGIN
        SELECT @waarde_oud = (SELECT @waarde FROM Deleted)
        SELECT @waarde_nieuw = (SELECT @waarde FROM Inserted)
        SELECT @gebruiker =  SYSTEM_USER
        exec [dbo].[PRODUCTS] @waarde,'PRODUCTS',@waarde_oud,@waarde_nieuw,@gebruiker
    
    END 
    CLOSE products_cursor
DEALLOCATE  products_cursor


Hij loopt vast op regel 29, met andere woorden, het insert-statement loopt vast, als ik dit in commentaar zet loopt het niet vast.
Aan het statement zelf ligt het niet, dit heb ik afzonderlijk getest en simpelere inserts geplaatst met het invoegen van een hardgecodeerde parameter in 1 veld lopen ook vast.

Iemand een idee, k snap echt niet wat er fout kan zijn.

  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09-2025

d00d

geen matches

Ik begrijp niet zo goed wat je probeert te bereiken.
Ik zie dat je het volgende doet:
1. maak een tijdelijke tabel aan met 1 veld genaamd list_item
2. haal van de products de eerste kolomnaam op (alfabetisch) en zet deze in de tijdelijke tabel
3. voer een stored procedure uit, die ook products heet, en geef de kolumnaam, tabelnaam, een willekeurige waarde uit de Deleted tabel (want geen order by en kan in geval van een insert ook NULL zijn), een willekeurige waarde uit de Inserted tabel (want geen order by) en de gebruikersnaam mee.

Er is nogal wat mis met deze code. Wat probeer je eigenlijk te bereiken?
Verder geef je aan dat het misgaat in regel 29 dus zou het beter zijn om de code van de stored procedure "Products" te posten.

42.7 percent of all statistics are made up on the spot.


Verwijderd

Topicstarter
Ik heb de namen veranderd en was de naam van de stored procedure vergeten aan te passen, de top 1 heb ik er gezet om te testen met slechts 1 veld, maar die zou eigenlijk ook weg moeten:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE TRIGGER Update_Products
 ON [dbo].[PRODUCTS] 
FOR INSERT,UPDATE
AS
create table #MyInternalList (
list_item    varchar(300) not null)

insert #MyInternalList
exec ( "SELECT    syscolumns.name AS column_name
FROM         sysobjects INNER JOIN
                      syscolumns ON sysobjects.id = syscolumns.id INNER JOIN
                      systypes ON syscolumns.xtype = systypes.xtype
WHERE     (sysobjects.xtype = 'U') AND (sysobjects.name = 'PRODUCTS')
ORDER BY sysobjects.name, syscolumns.colid" )

DECLARE @waarde as varchar(100)
DECLARE @waarde_oud VARCHAR(5000)
DECLARE @waarde_nieuw VARCHAR(5000)
DECLARE @gebruiker VARCHAR(150)
DECLARE products_cursor CURSOR FOR 
    SELECT * FROM #MyInternalList
    OPEN products_cursor
    FETCH products_cursor INTO @waarde
    WHILE @@fetch_status = 0
    BEGIN
        SELECT @waarde_oud = (SELECT @waarde FROM Deleted)
        SELECT @waarde_nieuw = (SELECT @waarde FROM Inserted)
        SELECT @gebruiker =  SYSTEM_USER
        exec [dbo].[UPDATE_PRODUCTS_HISTORY] @gebruiker,@waarde,'PRODUCTS',@waarde_oud,@waarde_nieuw,'UPDATE_INSERT'
    
    END 
    CLOSE products_cursor
DEALLOCATE  products_cursor


Ik maak dus een tijdelijke tabel aan met 1 veld, vervolgens vul ik deze met alle veldnamen van een opgegeven tabel.
Daarna ga ik met een cursor deze velden overlopen in de tijdelijke tabel en per veld de oude en de nieuwe waarde ophalen en wegschrijven naar de stored procedure UPDATE_PRODUCTES_HISTORY

Deze stored procedure schrijft weg naar de tabel PRODUCTS_HISTORY:
history_id int
datum datetime
gebruiker
veld
tabel
waarde_oud
waarde_nieuw
actie varchar

De stored procedure:

code:
1
2
3
4
5
6
7
8
9
10
11
12
CREATE PROCEDURE UPDATE_PRODUCTS_HISTORY
(
@gebruiker as varchar(150),
@veld  as varchar(300),
@tabel as varchar(300),
@waarde_oud as varchar(5000),
@waarde_nieuw as varchar(5000),
@actie as varchar(300))
AS
insert into PRODUCTS_HISTORY(datum,gebruiker,veld,tabel,waarde_oud,waarde_nieuw,actie)
values (getdate(),@gebruiker,@veld,@tabel,@waarde_oud,@waarde_nieuw,@actie)
GO

Verwijderd

Topicstarter
Hoe dom van me, in de cursor zit een oneindige loop, ik was fetch next from into vergeten...

Hetvolgende werkt wel nog niet:

SELECT @waarde_oud = (SELECT @waarde FROM Deleted)

@waarde is dus de kolomnaam in een string zoals product_title, in de logtabel zet hij echter nog steeds die naam "product_title" terwijl als ik hetvolgende doe:

SELECT @waarde_oud = (SELECT product_title FROM Deleted)
dan wordt wel de titel in de logtabel gezet bijvoorbeeld 'netwerkswitch".

De variabele @waarde schrijf ik ook weg en die is nogthans identiek aan "product_title".