Announcement

Collapse
No announcement yet.

If-Condition auf Spaltenänderung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • If-Condition auf Spaltenänderung

    Hallo,

    ich möchte einen Updatetrigger erstellen, der prüft ob die Änderung in einer bestimmten Spalte stattgefunden hat und wenn ja eine Aktion ausführt oder eben nicht.

    Wie kann ich im Trigger prüfen ob die geforderte Spalte geändert wurde?

    Danke Vaultboy

  • #2
    Bei einem Update-Trigger stehen die alten Werte in der Tabelle 'deleted' und die neuen Werte in 'inserted'. Allerdings muss man aufpassen, wieviele Records drinnen stehen, denn ein Trigger wird nur am Ende des Updates aufgerufen und nicht bei jedem einzelnen Record, man müsste dann also mit einem Cursor durch die Records gehen. Und dann am besten Spaltenweise vergleichen.
    Ein Beispiel - nehmen wir an, jeder Record hat eine eindeutige ID als PK und dann ein paar Felder:
    Code:
    declare @id int
    declare c1 cursor for select id from inserted
    open c1
    fetch next from c1 into @id
    while @@fetch_status = 0 begin
    
      if ( (select feld1 from inserted where id = @id) is NULL and
        (select feld1 from deleted where id = @id) is not NULL ) or
      ( (select feld1 from inserted where id = @id) is not NULL and
        (select feld1 from deleted where id = @id) is NULL ) or
      ( (select feld1 from inserted where id = @id) <>
        (select feld1 from deleted where id = @id) ) .... feld hat sich geändert
    
      if ( (select feld2 from inserted where id = @id) is NULL and
        (select feld2 from deleted where id = @id) is not NULL ) or
      ( (select feld2 from inserted where id = @id) is not NULL and
        (select feld2 from deleted where id = @id) is NULL ) or
      ( (select feld2 from inserted where id = @id) <>
        (select feld2 from deleted where id = @id) ) .... feld hat sich geändert
    
       ...
    
      fetch next from c1 into @id
    end
    close c1
    deallocate c1
    Natürlich könnte man auch UPDATE(spaltenname) verwenden, allerdings gibt das immer true, wenn die Spalte im Update-Statement steht, auch wenn der Wert selber nicht geändert wurde.

    bye,
    Helmut

    Comment


    • #3
      Das ginge auch, zum Beispiel, sich die Werte als Listen zu selectieren.

      Hier mal ein Testbeispiel, zum Einsatz einfach #del und #ins ersetzen, aber das kriegste schon hin :

      Code:
      create table #ins(id uniqueidentifier primary key, wert nvarchar(100) null)
      create table #del(id uniqueidentifier primary key, wert nvarchar(100) null)
      
      declare @ID uniqueidentifier; set @id = newid()
      declare @ID2 uniqueidentifier; set @id2 = newid()
      
      insert into #ins(id, wert) values (@ID, 'Wert')
      insert into #ins(id, wert) values (@ID2, 'Wert2')
      
      insert into #del(id, wert) values (@ID, 'Wert')
      insert into #del(id, wert) values (@ID2, 'Wert2')
      
      select * from #ins ins inner join #del del on ins.id = del.id 
      where isnull(ins.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich') != isnull(del.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich')
      
      /* test - NULLVALUE */
      delete from #ins; delete from #del;
      
      insert into #ins(id, wert) values (@ID, 'Wert')
      insert into #ins(id, wert) values (@ID2, null)
      
      insert into #del(id, wert) values (@ID, 'Wert')
      insert into #del(id, wert) values (@ID2, 'Wert2')
      
      select * from #ins ins inner join #del del on ins.id = del.id 
      where isnull(ins.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich') != isnull(del.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich')
      
      /* test - VALUECHANGE */
      delete from #ins; delete from #del;
      
      insert into #ins(id, wert) values (@ID, 'Wert')
      insert into #ins(id, wert) values (@ID2, 'WertXY')
      
      insert into #del(id, wert) values (@ID, 'WertVergleich')
      insert into #del(id, wert) values (@ID2, 'Wert2')
      
      select * from #ins ins inner join #del del on ins.id = del.id 
      where isnull(ins.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich') != isnull(del.wert, N'hieristkeinwertdrindasistnureinganzlangeraliaszumvergleich')
      
      drop table #ins
      drop table #del

      Comment

      Working...
      X