Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

trigger e transazioni su tavoli temporanei

Non penso che tu capisca i trigger:l'attivazione del trigger è associata all'istruzione a cui sono correlati, piuttosto che al momento del commit della transazione. Due script:

Script 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

Script 2:

select * from T2 with (nolock)

Aprire due connessioni allo stesso DB, inserire uno script in ciascuna connessione. Esegui script 1. Quando viene visualizzato il messaggio "Esegui lo script 2 ora", passa all'altra connessione. Vedrai che sei in grado di selezionare i dati non vincolati da T2, anche se tali dati vengono inseriti dal trigger. (Ciò implica anche che i blocchi appropriati vengano mantenuti su T2 dallo script 1 fino al commit del trigger).

Poiché ciò implica che l'equivalente di ciò che stai chiedendo è semplicemente inserirlo nella tabella di base e tenere aperta la transazione, puoi farlo.

Se desideri nascondere agli utenti la forma effettiva della tabella, crea una vista e scrivi i trigger su quello per aggiornare le tabelle di base. Come affermato in precedenza, tuttavia, non appena avrai eseguito un'operazione DML contro la vista, i trigger verranno attivati ​​e manterrai i blocchi contro la tabella di base. A seconda del livello di isolamento della transazione di altre connessioni, potrebbero vedere le tue modifiche o essere bloccate fino al commit della transazione.