2014-02-18 32 views
2

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

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,但我不知道为什么。谢谢!

+0

失去开始和结束。他们只是让你的整个SP都缩进一层。 – ErikE

+0

只是想感谢大家所有有用的答案 – TwinPrimesAreEz

回答

2

你们没有提到会影响性能的事情,而在现实中,它是个人喜好,但这里是我的想法:

没有,除非你想改变从返回的值,你不需要RETURN默认值为0.这对于程序中的returning error codes很有用。

你是否包括BEGIN/END并不重要,但是我建议你这样做,主要原因是为了防止错误,例如,如果我想创建一个从2个表中选择ID的过程, foo和酒吧,并运行以下命令:

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

的程序将被创建,我会从酒吧得到的ID,并且该过程会留下刚刚返回从富的ID。如果我在BEGIN/END包围的过程那就不是编译:

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

你不能保护自己免受所有的错误和错别字,我们都让他们不时,但每一点帮助!

最后,不要紧,你是否之前或之后BEGINSET NOCOUNT,但在与BEGIN/END包装整个过程的惯例那么我认为BEGIN后应该去。

很多这是源于this articleAaron Bertrand,并总结为这个具体问题。我是他所有最佳实践指南的忠实粉丝,这也不例外。

+0

非常好的分析,谢谢 – TwinPrimesAreEz

+0

我只是不同意BEGIN和END。对我来说,让我所有的代码缩进一个额外的区块比防止可能的“GO”漏洞更有价值。在10年的SQL Server工作中,我从来没有一次意外地通过使用流浪的GO来切断SP。但我经历了太多的缩进。 – ErikE

+1

@ErikE正如我所说,它基本上只是个人偏好,虽然我无法回想一个流浪'GO'导致我遇到问题的情况,但我也不记得缩进导致我遇到问题的情况(既然查询分析器对于SQL Server 2000,当前一行的缩进不被记住,并且每次都必须按Tab键)。鉴于缩进是可选的,也就是说,您可以将查询的其余部分保留在与第一个“BEGIN”相同的缩进处,并且这绝不会产生意想不到的行为,它似乎是两个“邪恶”中较小的一个。 – GarethD

0

我总是在BEGIN声明后的第一行包含SET NOCOUNT ON

如果您正在阅读使用应用程序的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 
+0

这实际上我通常也包括它,但我真的不知道为什么。那么你是说在开始语句之前放置SET NO COUNT,而不是在它会引起额外的消息之后? – TwinPrimesAreEz

+0

不,我说的是把'SET NOCOUNT OFF'而不是'SET NOCOUNT ON'会产生额外的消息。 “SET NOCOUNT ON”可以在“AS”后的任何时间,但在您返回之前。 – 2014-02-18 17:47:25

+0

好吧。我只是在某个地方看过你应该这样做(即使我从来没有这样做) – TwinPrimesAreEz

0

你不需要返回。

将NOCOUNT设置为OFF(这是默认设置 - 对我来说),您会得到每个语句的结果集(也可能只是为了让您感到困惑而关闭)。这包括插入和更新,几乎肯定不是你想要的。一些提供程序(带有服务器游标的ADO)只能处理一条记录,并且如果有多条记录会引发异常 - 通常会出现非常难看的错误消息。如果有多个语句,则只需要SET NOCOUNT ON - 在您的情况下不存在。

我听说过SET SET NOCOUNT OFF是很好的做法,但它可能并不重要。

您的BEGIN和ENDs在这种情况下没有任何区别。

+0

这也是我所听到的。你知道为什么吗?我个人不这样做(我的存储过程都非常基本,我是唯一一个在这个数据库上进行任何开发的人) – TwinPrimesAreEz

+0

我认为这只是一种很好的做法。如果关闭连接上的标志,则应重新打开它(反之亦然)。如果您正在使用的连接被集中,那么标志可能会持续存在,并可能影响其他呼叫。例如,返回受影响记录数的执行调用*可能需要NOCOUNT OFF。 – Rob

+0

好的。谢谢 – TwinPrimesAreEz