Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

déclencheur et transactions sur les tables temporaires

Je ne pense pas que vous compreniez les déclencheurs - le déclenchement des déclencheurs est associé à l'instruction à laquelle ils sont liés, plutôt qu'au moment où la transaction est validée. Deux scripts :

Scénario 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

Scénario 2 :

select * from T2 with (nolock)

Ouvrez deux connexions à la même base de données, placez un script dans chaque connexion. Exécutez le script 1. Lorsqu'il affiche le message "Exécuter le script 2 maintenant", passez à l'autre connexion. Vous verrez que vous pouvez sélectionner des données non validées à partir de T2, même si ces données sont insérées par le déclencheur. (Cela implique également que les verrous appropriés sont maintenus sur T2 par le script 1 jusqu'à ce que le déclencheur soit validé).

Puisque cela implique que l'équivalent de ce que vous demandez est simplement d'insérer dans la table de base et de maintenir votre transaction ouverte, vous pouvez le faire.

Si vous souhaitez masquer la forme réelle du tableau aux utilisateurs, créez une vue et écrivez des déclencheurs dessus pour mettre à jour les tables de base. Comme indiqué ci-dessus, dès que vous aurez effectué une opération DML sur la vue, les déclencheurs se seront déclenchés et vous maintiendrez des verrous sur la table de base. Selon le niveau d'isolement de la transaction des autres connexions, elles peuvent voir vos modifications ou être bloquées jusqu'à ce que la transaction soit validée.