ALTER PROCEDURE [dbo].[cor_InsertServerConfig]
(
@ServerName varchar(20),
@ServerIP varchar(20),
@ServerCategory varchar(25),
@ServerState char(1),
@ServerAbility int
--@ID int output
)
AS
DECLARE @ID INT
BEGIN transaction
SET NOCOUNT ON;
IF EXISTS ( SELECT 1 FROM [ServerConfig] WHERE ServerName = @ServerName)
BEGIN
--return 0
--SELECT @ID = 0
SET @ID = 0
RETURN @ID
END
ELSE
BEGIN
INSERT INTO [ServerConfig](ServerName,ServerIP,ServerCategory,ServerState,ServerAbility)
VALUES (@ServerName,@ServerIP,@ServerCategory,@ServerState,@ServerAbility)
--SELECT ID FROM INSERTED --C#里'INSERTED'对象名无效
--SELECT SCOPE_IDENTITY()
set @ID = @@identity
commit transaction
---select @ID 非Output,而是return,用select 即使成功插入返回的也为0
return @ID
END
当SELECT 1 FROM [ServerConfig] WHERE ServerName = @ServerName时出现上面的错误。
Begin Tran
....
Commit Tran
中间不能出现 return,因为BEGIN TRANSACTION 语句将 @@TranCount加 1。ROLLBACK TRANSACTION 将 @@TranCount递减到 0, return 使执行进程返回,但并没有使事务计数器减一,所以出现了语句执行后事务计数器出现不一致的情况....
ALTER PROCEDURE [dbo].[cor_InsertServerConfig]
(
@ServerName varchar(20),
@ServerIP varchar(20),
@ServerCategory varchar(25),
@ServerState char(1),
@ServerAbility int
--@ID int output
)
AS
DECLARE @ID INT
BEGIN transaction
SET NOCOUNT ON;
IF EXISTS ( SELECT 1 FROM [ServerConfig] WHERE ServerName = @ServerName)
BEGIN
--return 0
--SELECT @ID = 0
SET @ID = 0
ROLLBACK TRANSACTION
RETURN @ID
END
ELSE
BEGIN
INSERT INTO [ServerConfig](ServerName,ServerIP,ServerCategory,ServerState,ServerAbility)
VALUES (@ServerName,@ServerIP,@ServerCategory,@ServerState,@ServerAbility)
--SELECT ID FROM INSERTED --C#里'INSERTED'对象名无效
--SELECT SCOPE_IDENTITY()
set @ID = @@identity
commit transaction
---select @ID 非Output,而是return,用select 即使成功插入返回的也为0
return @ID
END
这样就正确了。
另外这种情况
ALTER PROCEDURE [dbo].[sp_test]
AS
BEGIN
SET NOCOUNT ON;
set xact_abort on
--开始显式声明事务
begin tran
INSERT INTO [testDB].[dbo].[test]
([name])
VALUES
(CAST(getdate() AS nvarchar(20)))
return @@rowcount
commit tran
END
执行时出现了“ EXECUTE 后的事务计数指示缺少了 COMMIT 或 ROLLBACK TRANSACTION 语句”
到Google上查找原因,发现是
“如果某存储过程退出时其 @@TRANCOUNT 值与进入该存储过程时不同,则 SQL Server 返回错误 266。 ”
再到MSDN上找原因,发现这么一条备注
“BEGIN TRANSACTION 语句将 @@TRANCOUNT 加 1。ROLLBACK TRANSACTION 将 @@TRANCOUNT 递减到 0,但 ROLLBACK TRANSACTION savepoint_name 除外,它不影响 @@TRANCOUNT。COMMIT TRANSACTION 或 COMMIT WORK 将 @@TRANCOUNT 递减 1。”
此时,原因已经明了了,出在这句话上:
return @@rowcount
commit tran
return 使执行进程返回,但并没有使事务计数器减一,所以出现了语句执行后事务计数器出现不一致的情况,报告“消息 266,级别 16,状态 2,过程 sp_test,第 0 行”错误。