Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Trigger und Transaktionen auf temporären Tabellen

Ich glaube nicht, dass Sie Trigger verstehen - das Auslösen von Triggern ist mit der Aussage verbunden, auf die sie sich beziehen, und nicht, wenn die Transaktion festgeschrieben wird. Zwei Skripte:

Skript 1:

create table T1 (
    ID int not null,
    Val1 varchar(10) not null
)
go
create table T2 (
    ID int not null,
    Val2 varchar(10) not null
)
go
create trigger T_T1_I
on T1
after insert
as
    insert into T2 (ID,Val2) select ID,Val1 from inserted
go
begin transaction
insert into T1 (ID,Val1)
select 10,'abc'
go
RAISERROR('Run script 2 now',10,1) WITH NOWAIT
WAITFOR DELAY '00:01:00'
go
commit

Skript 2:

select * from T2 with (nolock)

Öffnen Sie zwei Verbindungen zu derselben DB und fügen Sie in jede Verbindung ein Skript ein. Führen Sie Skript 1 aus. Wenn die Meldung „Run script 2 now“ angezeigt wird, wechseln Sie zur anderen Verbindung. Sie werden sehen, dass Sie nicht festgeschriebene Daten aus T2 auswählen können, obwohl diese Daten vom Trigger eingefügt wurden. (Dies impliziert auch, dass entsprechende Sperren auf T2 von Skript 1 gehalten werden, bis der Trigger festschreibt).

Da dies impliziert, dass das Äquivalent zu dem, wonach Sie fragen, darin besteht, einfach in die Basistabelle einzufügen und Ihre Transaktion offen zu halten, können Sie das tun.

Wenn Sie die tatsächliche Form der Tabelle vor Benutzern verbergen möchten, erstellen Sie eine Ansicht und schreiben Sie Trigger darauf, um die Basistabellen zu aktualisieren. Wie oben erwähnt, werden die Trigger ausgelöst, sobald Sie eine DML-Operation für die Ansicht ausgeführt haben, und Sie halten Sperren für die Basistabelle. Abhängig von der Transaktionsisolationsstufe anderer Verbindungen können diese Ihre Änderungen sehen oder blockiert werden, bis die Transaktion festgeschrieben wird.