Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

trigger e transações em tabelas temporárias


Acho que você não entende os gatilhos - o disparo do gatilho está associado à instrução à qual eles estão relacionados, e não quando a transação é confirmada. Dois roteiros:

Roteiro 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

Roteiro 2:
select * from T2 with (nolock)

Abra duas conexões para o mesmo banco de dados, coloque um script em cada conexão. Executar script 1. Ao exibir a mensagem "Executar script 2 agora", alterne para a outra conexão. Você verá que pode selecionar dados não confirmados de T2, mesmo que esses dados sejam inseridos pelo gatilho. (Isso também implica que os bloqueios apropriados estão sendo mantidos em T2 pelo script 1 até que o gatilho seja confirmado).

Como isso implica que o equivalente ao que você está pedindo é apenas inserir na tabela base e manter sua transação aberta, você pode fazer isso.

Se você quiser ocultar a forma real da tabela dos usuários, crie uma visualização e escreva gatilhos para atualizar as tabelas base. Como dito acima, assim que você executar uma operação DML na exibição, os gatilhos serão acionados e você estará mantendo bloqueios na tabela base. Dependendo do nível de isolamento da transação de outras conexões, elas podem ver suas alterações ou ser bloqueadas até que a transação seja confirmada.