我在玩SET IMPLICIT_TRANSACTIONS ON
. 我发现了一种情况,我确信数据库会自动创建并提交一个事务,而不会让它保持打开状态。如果我这样做IF EXISTS (SELECT * FROM dbo.t1)
或有任何变化,我确定交易正在后台发生,如果我使用隐式交易,我希望它保持开放状态。
但是,在阅读文档之后,它说的是这样的:
这意味着如果
@@TRANCOUNT = 0
,以下任何 Transact-SQL 语句都会开始一个新事务。
并且它显示的列表不包括IF
. 但是,我希望在文档列表中找不到的所有语句都不会@@TRANCOUNT
递增。因此,我寻找了另一个未包含在该列表中的声明。我发现DECLARE
。但是,我发现如果我使用 执行子查询DECLARE
,我会得到我期望的行为SET IMPLICIT_TRANSATIONS ON
。也就是说,如果 my有一个子查询,如果它为零DECLARE
,它就会递增。@@TRANCOUNT
所以看起来文档与自身不一致
SET IMPLICIT_TRANSACTIONS ON
GO
IF OBJECT_ID('dbo.t1') IS NOT NULL
BEGIN
DROP TABLE dbo.t1
COMMIT
END
GO
CREATE TABLE dbo.t1 (x INT);
COMMIT;
GO
IF CASE WHEN EXISTS (SELECT * FROM dbo.t1) THEN 1 ELSE 0 END = 1 PRINT 'unreachable';
PRINT 'after1 ' + CAST(@@TRANCOUNT AS VARCHAR(MAX)); -- after1 0
DECLARE @x INT = 2;
PRINT 'after2 ' + CAST(@@TRANCOUNT AS VARCHAR(MAX)); -- after2 0
DECLARE @y INT = CASE WHEN EXISTS (SELECT * FROM dbo.t1) THEN 1 ELSE 0 END;
PRINT 'after3 ' + CAST(@@TRANCOUNT AS VARCHAR(MAX)); -- after3 1
GO
WHILE @@TRANCOUNT > 0 ROLLBACK
GO
为什么嵌入式而不是DECLARE
增量?嵌入在某种程度上实际上没有使用事务吗?@@TRANCOUNT
SELECT
IF
SELECT
IF
我正在使用 SQL Server 13.0.4411。
我怀疑您所看到的是因为某些语句
SELECT
在幕后转换为语句,而另一些则没有。考虑你的最后DECLARE
陈述:这只是这个的简写:
也可以这样写:
在这种情况下,您希望看到
@@TRANCOUNT
增加。但是,你能对声明做出同样的IF
声明吗?如果我在启用实际执行计划的情况下运行您的原始代码,我会看到以下内容:我没有
SELECT
在第一个查询的计划中看到 a。我只看到COND WITH QUERY
。所以它似乎与文档一致。