下面是隐式事务吗?并且最后2个@是干啥的
SELECT * FROM bookinfo
BEGIN TRANSACTION INSERT_DATA --开始事务
INSERT INTO bookinfo(ISBN,BookName)
VALUES('7-111-15643-1','C语言程序开发范例宝典')
COMMIT TRANSACTION INSERT_DATA --提交事务
IF @@ERROR = 0
PRINT '数据添加成功!'代码逐行详解
你这个问题问得非常到位——这根本不是隐式事务,而是显式事务。我先把最关键的结论告诉你,然后再逐行拆解。
一、先回答你两个核心问题
1️⃣ “怎么没看出来是隐式的?”
因为这段代码用的就是显式事务,不是隐式事务。
| 事务类型 | 特征 | 本例是否符合 |
|---|---|---|
| 隐式事务 | 不需要写 BEGIN TRANSACTION,每个 SQL 自动成为事务 | ❌ 不符合 |
| 显式事务 | 必须写 BEGIN TRANSACTION / COMMIT / ROLLBACK | ✅ 符合 |
👉 你感觉“没看出隐式”,是对的——因为它根本不是隐式。
2️⃣ “最后两个 @ 是干啥的?”
@@ERROR 是 SQL Server 的系统全局变量(以 @@ 开头)。
| 符号 | 含义 | 例子 |
|---|---|---|
@ | 用户自定义变量 | @myVar |
@@ | 系统全局变量 | @@ERROR、@@ROWCOUNT、@@IDENTITY |
二、逐行拆解这段代码
第 1 行
sql
SELECT * FROM bookinfo
在事务之前查询表
可以看到事务执行前的数据状态
第 2 行
sql
BEGIN TRANSACTION INSERT_DATA --开始事务
显式开启一个事务
INSERT_DATA是事务的名称(可自定义)👉 这已经是显式事务的标志
第 3–4 行
sql
INSERT INTO bookinfo(ISBN,BookName)
VALUES('7-111-15643-1','C语言程序开发范例宝典')实际的数据插入操作
在
COMMIT之前,这条数据还没有真正写入磁盘
第 5 行
sql
COMMIT TRANSACTION INSERT_DATA --提交事务
正式把刚才的插入永久保存到数据库
第 6 行
sql
IF @@ERROR = 0
@@ERROR:SQL Server 系统变量,表示上一条 SQL 语句的错误号0= 没有错误 ✅非
0= 有错误 ❌这里检查的是第 3–4 行的
INSERT是否成功
第 7 行
sql
PRINT '数据添加成功!'
如果没有错误,输出成功信息
三、隐式事务的正确写法(和你这段代码对比)
隐式事务长这样(你根本看不到 BEGIN):
sql
SET IMPLICIT_TRANSACTIONS ON -- 开启隐式事务模式INSERT INTO bookinfo(ISBN,BookName) VALUES(...) -- 自动成为事务COMMIT TRANSACTION -- 必须手动提交
👉 你给出的代码完全不满足这个特征。
四、@@ERROR 的历史与使用注意事项
词源
@@:SQL Server 时代沿用下来的系统变量前缀ERROR:错误
正确使用方式
sql
INSERT ...IF @@ERROR = 0 PRINT '成功'ELSE PRINT '失败'
⚠️ 重要:@@ERROR 会被每一条 SQL 重置,所以必须紧跟在被检查的语句后面。
五、现代替代方案(你了解一下就行)
在 SQL Server 2005+ 中,推荐用 TRY...CATCH:
sql
BEGIN TRY BEGIN TRANSACTION INSERT INTO bookinfo(ISBN,BookName) VALUES(...) COMMIT PRINT '成功'END TRYBEGIN CATCH ROLLBACK PRINT '失败'END CATCH
六、一个非常容易混淆的点(面试常见)
| 概念 | 是否写 BEGIN | 是否写 COMMIT |
|---|---|---|
| 隐式事务 | ❌ 不写 | ✅ 必须写 |
| 显式事务 | ✅ 必须写 | ✅ 必须写 |
| 自动提交(默认) | ❌ 不写 | ❌ 不写 |
SQL Server 默认是自动提交模式(每条 SQL 自动提交),不在你当前讨论范围内。
七、总结一句话
你给的这段代码是标准的显式事务,不是隐式事务。
@@ERROR是用来判断上一条 SQL 是否执行成功的系统变量。