灵感来自这个问题,对于SET NOCOUNT有不同的看法......
我们应该为SQL Server使用SET NOCOUNT ON吗?如果没有,为什么不呢?
它的作用编辑6,2011年7月22日
它会在任何DML之后抑制"xx行受影响"消息.这是一个结果集,当发送时,客户端必须处理它.它很小,但可以测量(见下面的答案)
对于触发器等,客户端将收到多个"受影响的xx行",这会导致某些ORM,MS Access,JPA等出现各种错误(参见下面的编辑)
背景:
一般接受的最佳实践(我想直到这个问题)是SET NOCOUNT ON在SQL Server中的触发器和存储过程中使用.我们在任何地方都使用它,快速谷歌显示大量的SQL Server MVP也同意.
MSDN表示这可能会破坏.net SQLDataAdapter.
现在,这对我来说意味着SQLDataAdapter仅限于完全简单的CRUD处理,因为它希望"n行受影响"消息匹配.所以,我不能用:
在问题marc_s(谁知道他的SQL的东西)说不要使用它.这与我的想法不同(我认为自己在SQL方面也有一定的能力).
有可能我错过了一些东西(随意指出明显的东西),但你们有什么想法呢?
注意:我看到这个错误已经好几年了,因为我现在不使用SQLDataAdapter.
在评论和问题后编辑:
编辑:更多想法......
我们有多个客户端:一个可以使用C#SQLDataAdaptor,另一个可以使用Java中的nHibernate.这些可能会以不同的方式受到影响SET NOCOUNT ON.
如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的而工作则是不好的形式(反模式).
编辑2:触发器打破nHibernate问题,SET NOCOUNT ON无法设置
(不,它不是一个重复的这个)
编辑3:更多信息,感谢我的MVP同事
编辑2011年5月13日
编辑2011年6月14日
使用表变量打破JPA,存储过程:JPA 2.0是否支持SQL Server表变量?
编辑6:2011年8月15日
SSMS"编辑行"数据网格需要SET NOCOUNT ON:使用GROUP BY更新触发器
编辑2013年3月7日7:07
来自@RemusRusanu的更深入的细节:
SET NOCOUNT …
如果你小心并且在所有内容周围使用TRY-CATCH,并且你真的需要使用以下错误回滚:
SET XACT_ABORT ON
Run Code Online (Sandbox Code Playgroud)
换句话说,是否有任何错误,TRY-CATCH将错过SET XACT_ABORT ON将处理?
您认为在t-sql中编写事务有更好的方法吗?是否有更好的方法可以提高使用此事务的应用程序的可维护性和性能?
-- Description: Insert email Receiver under specified subject
-- =============================================
ALTER PROCEDURE [Contact].[Receiver_stpInsert]
@First_Name nvarchar(30),
@Last_Name nvarchar(30),
@Email varchar(60),
@Subject_Id int
AS
BEGIN
SET NOCOUNT ON;
DECLARE @error_num int;
BEGIN TRANSACTION
INSERT INTO Contact.Receiver(First_Name, Last_Name, Email) VALUES(@First_Name, @Last_Name, @Email);
SET @error_num = @@ERROR;
IF (@error_num <> 0)
BEGIN
ROLLBACK;
RETURN;
END
DECLARE @rec_record_id int;
SET @rec_record_id = (SELECT Record_Id FROM Contact.Receiver WHERE Email = @Email);
SET @error_num = @@ERROR;
IF (@error_num <> 0)
BEGIN
ROLLBACK;
RETURN;
END
INSERT INTO …Run Code Online (Sandbox Code Playgroud) 您可以在一个存储过程中启动事务,然后将其回滚或在嵌套过程中提交吗?
我在某些情况下看到了交易使用情况,但从未真正理解应该在哪些情况下使用它们.应该如何以及何时使用交易(开始交易声明)?我已经读过微软不建议在触发器和存储过程中使用事务语句(commit,rollback).
sql-server stored-procedures transactions sql-server-2005 sql-server-2008
我得到关于提交和回滚的这个例外,但我不确定我的存储过程究竟出了什么问题.我已经阅读了其他类似问题的答案,但我无法找到确切的提交计数在哪里搞砸了.
所以,这是我使用的存储过程:
-- this is a procedure used for the purge utility. This procedure uses the parameters of a date and lets user select
-- if the leads that should be purge must be closed either before, on or since that date.
-- operator: 0-->less 1-->equal 2-->greater
-- @closed: closing date
-- leadscount: returns the count of leads deleted
IF OBJECT_ID ('LEAD_PURGE', 'P') IS NOT NULL
DROP PROCEDURE LEAD_PURGE
go
CREATE PROCEDURE LEAD_PURGE
@purgextns INT,
@leadscount INT OUTPUT
AS
BEGIN …Run Code Online (Sandbox Code Playgroud) 现在我和一位同事正在争论非重要的BEGIN TRAN ...... COMMIT TRAN块的影响.我已经为简单的插入更新删除操作写了大约140个存储过程,因为我们以后可能需要在它们中做一些额外的操作,我已经包含了可能是必要的BEGIN TRAN和COMMIT TRAN块,如下所示:
CREATE PROCEDURE [Users].[Login_Insert]
@Username nvarchar (50) OUTPUT,
@Password char (40),
@FullName nvarchar (150),
@LoginTypeId int
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
INSERT [Users].[Login]
(
[Username],
[Password],
[FullName],
[LoginTypeId]
)
VALUES
(
@Username,
@Password,
@FullName,
@LoginTypeId
)
COMMIT TRAN
RETURN 1
END TRY
BEGIN CATCH
ROLLBACK TRAN
RETURN -1
END CATCH
GO
Run Code Online (Sandbox Code Playgroud)
现在许多这些交易可能永远不必要.这些无关的块是否会以明显的方式影响性能?提前致谢.
为了在事务中包装存储过程,我添加以下内容:
CREATE PROCEDURE [dbo].[P_ORD_InsertTextField]
//PARAMS
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
//STP BODY
COMMIT
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK
DECLARE @ErrMsg nvarchar(4000), @ErrSeverity int
SELECT @ErrMsg = ERROR_MESSAGE(),
@ErrSeverity = ERROR_SEVERITY()
RAISERROR(@ErrMsg, @ErrSeverity, 1)
END CATCH
END
GO
Run Code Online (Sandbox Code Playgroud)
有没有更短的方式做同样的事情?这是"只是"处理事务的巨大代码块.
这是我第一次使用交易,我只是想知道我做对了.我应该改变什么吗?我插入帖子(wisp).插入帖子时我需要在commentableEntity表中生成ID并在wisp表中插入该ID.
ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,
@m_WispTypeId int,
@m_CreatedOnDate datetime,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
AS
BEGIN TRANSACTION
DECLARE @wispId int
INSERT INTO dbo.tbl_Wisps
(UserId,WispTypeId,CreatedOnDate,PrivacyTypeId,WispText)
VALUES
(@m_UserId,@m_WispTypeId,@m_CreatedOnDate,@m_PrivacyTypeId,@m_WispText)
if @@ERROR <> 0
BEGIN
ROLLBACK
RAISERROR ('Error in adding new wisp.', 16, 1)
RETURN
END
SELECT @wispId = SCOPE_IDENTITY()
INSERT INTO dbo.tbl_CommentableEntity
(ItemId)
VALUES
(@wispId)
if @@ERROR <> 0
BEGIN
ROLLBACK
RAISERROR ('Error in adding commentable entity.', 16, 1)
RETURN
END
DECLARE @ceid int
select @ceid = SCOPE_IDENTITY()
UPDATE dbo.tbl_Wisps SET CommentableEntityId = …Run Code Online (Sandbox Code Playgroud) 我有一个SP(存储过程),其中包含一些T-SQL语句.....
所有T-sql语句都在一个事务块中,并且通过发生任何错误,我回滚所有事情.
像这样:
BEGIN TRANSACTION
.....
.....
IF @X=1
BEGIN
declare cu cursor for select col1,col2 from Table1 where Id=@Y
open cu
fetch next from cuinto @A, @B
while @@Fetch_Status = 0
BEGIN
.....
......
IF @@ERROR <>0
BEGIN
ROLLBACK TRANSACTION
RETURN
END
END
.....
.....
Run Code Online (Sandbox Code Playgroud)
Sp没有正常运行,我无法找到它的重要内容.....我认为通过在表中插入一些数据来记录sp中的每个操作是个好主意我的问题是:
因为它使用了一个事务,所以每次插入都会被回滚.....
你怎么看?还有其他方法吗?
谢谢
sql-server ×10
transactions ×6
t-sql ×5
sql ×2
ado.net ×1
concurrency ×1
database ×1
java ×1
jdbc ×1
logging ×1
nested ×1
performance ×1
scope ×1