在存储过程中准确设置NOCOUNT的位置?

时间:2014-02-18 17:34:52

标签: asp.net sql tsql

我喜欢在ASP.NET中使用存储过程,并希望确保我具有完全正确的语法。这些之间有什么重大差异吗?

ALTER PROCEDURE dbo.mySP
    @param1
AS
    BEGIN
    SET NOCOUNT ON
    SELECT f1 FROM foo WHERE f2 = @param1
    END
RETURN

如果我们不使用开始,结束或返回怎么办?性能方面有什么不同吗?

ALTER PROCEDURE dbo.mySP
    @param1
AS
    SET NOCOUNT ON
    SELECT f1 FROM foo WHERE f2 = @param1

如果在BEGIN之前或之后设置了NOCOUNT,它会有所不同吗?

ALTER PROCEDURE dbo.mySP
    @param1
AS
    SET NOCOUNT ON
    BEGIN
    SELECT f1 FROM foo WHERE f2 = @param1
    END

我们真的需要回归吗? Visual Studio包含它,但没有它,一切似乎都很好。最后,我看到它建议在返回结果之前关闭NOCOUNT,但我不确定原因。谢谢!

3 个答案:

答案 0 :(得分:2)

你提到的所有事情都不会影响表现,实际上这是个人偏好,但这是我的想法:

否则您不需要RETURN,除非您想要从默认值0更改返回值。这对于过程中的returning error codes非常有用。

您是否包含BEGIN/END并不重要,但我建议您这样做,主要原因只是为了防止错误,例如,如果我想创建一个程序来从中选择ID 2个表,foo和bar,并执行以下操作:

CREATE PROCEDURE dbo.Test
AS
    SELECT ID
    FROM Foo;
    GO
    SELECT ID
    FROM Bar;
GO

将创建该过程,并且我将从Bar获取ID,并且将仅从Foo返回ID。如果我在BEGIN/END中附上了该程序,那么就不会编译:

CREATE PROCEDURE dbo.Test
AS
BEGIN
    SELECT ID
    FROM Foo;
    GO
    SELECT ID
    FROM Bar;
END
GO

你无法保护自己免受所有错误和错别字的侵害,而且我们都会不时地制作它们,但每一点都有帮助!

最后,在SET NOCOUNT之前或之后放置BEGIN并不重要,但是为了与用BEGIN/END包装整个过程的做法保持一致,那么我认为它应该去在BEGIN之后。

其中很多内容来自this article Aaron Bertrand,并针对此特定问题进行了总结。我是他所有最佳实践指南的忠实粉丝,也不例外。

答案 1 :(得分:0)

我总是在SET NOCOUNT ON语句后的第一行包含BEGIN

如果您正在使用应用程序阅读SP并且在SP上设置了SET NOCOUNT OFF。您将获得结果和消息。如果您不处理该附加消息的返回,您可能会遇到问题。

这就是为什么最好SET NOCOUNT ON这样你就不会得到额外的不重要的消息。

消息显示:

ALTER PROC test
AS
BEGIN   
    SELECT *
    FROM sys.tables
    SET NOCOUNT ON;
END

未显示消息:

ALTER PROC test
AS
BEGIN   
    SET NOCOUNT ON;
    SELECT *
    FROM sys.tables     
END

答案 2 :(得分:0)

您不需要RETURN。

NOCOUNT设置为OFF(这是默认值 - 对我来说无论如何),你会得到每个语句的结果集(也可能只是为了混淆你的更多而关闭)。这包括INSERT和UPDATES,几乎可以肯定不是你想要的。一些提供程序(带有服务器游标的ADO)将只处理一个记录,如果有多个记录将抛出异常 - 通常会出现一个非常难看的错误消息。如果有多个语句,您只需要SET NOCOUNT ON - 在您的情况下没有。

我听说它说SET NOCOUNT OFF是很好的做法,但它可能没关系。

你的BEGIN和ENDs在这种情况下没有区别。