2017-09-08 1 views
0

Le code suivant s'exécute comme prévu. La ligne est insérée.La validation de transaction a-t-elle démarré en SQL dynamique?

create table #t1(a datetime2) 

declare @s nvarchar(max) = N' 
-- Some expensive remote query should not be in the transaction 
begin tran 
insert #t1 select getdate()'; 

exec (@s); 

commit; -- replace commit to rollback will rollback the transaction 

select * from #t1 

Cependant, il a l'erreur suivante?

Msg 266, Niveau 16, État 2, Ligne 31

Nombre de transactions après EXECUTE indique un numéro de désadaptation de Begin et COMMIT. Nombre précédent = 0, nombre actuel = 1.

Mise à jour: J'ai trouvé que la déclaration insert dans le SQL dynamique ne sera pas exécutée si je mets le code dans un bloc try/catch. Cependant, il a toujours l'erreur.

begin try 

    declare @s nvarchar(max) = N' 
    -- Some expensive query should not be in the transaction 
    begin tran 
    insert #t1 select getdate()'; 
    exec (@s); 

    commit 

end try 
begin catch 
    select ERROR_NUMBER(), ERROR_MESSAGE(), ERROR_LINE(), @@TRANCOUNT 
    if @@TRANCOUNT > 0 
     rollback 
end catch 
select * from #t1 
+0

Qu'essayez-vous d'éviter ou d'éviter en empruntant cette route? –

+3

Ne pouvez-vous pas contenir 'exec (@s)' dans une transaction? – Leonidas199x

+2

Faites vos trucs de chaîne et enfin faire quelque chose comme ... BEGIN TRAN EXEC (@s) COMMIT –

Répondre

0

le moteur émet néanmoins une erreur sur le @@ décalage TRANCOUNT immédiatement après l'EXEC. En outre, cette erreur dooms la transaction quel que soit XACT_ABORT

La deuxième déclaration ici est pas vrai, comme l'exemple de la première OP montre, la transaction a commencé dans le code dynamique peut être engagée avec succès dans le cadre extérieur. Donc, la transaction n'est pas condamnée, c'est commissible.

Je n'ai pas trouvé la question dans l'OP. Si c'est à propos de quoi faire avec l'erreur 266, la réponse est juste l'ignorer.

266 message d'erreur est d'information uniquement, vous pouvez le voir ici: Rollbacks and Commits in Stored Procedures and Triggers:

Si @@ TRANCOUNT a une valeur différente lorsqu'une termine procédure stockée qu'il avait lorsque la procédure a été exécutée, une erreur d'information (266) se

Alors, que happend est le serveur ici enregistre @@TRANCOUNT lorsque vous exécutez une procédure stockée/s dynamiques ql et lorsque vous revenez à la portée externe, il contrôle si @@TRANCOUNT est le même que lorsque vous avez démarré le code sp/dynamique, si ce n'est pas le cas, il soulève l'erreur 266 qui est "ne terminant rien du tout".