存储过程中END之后的语句

Nel*_*mel 7 t-sql stored-procedures

我今天遇到了一个有趣的问题.我正在改变存储过程并在最后放置一个select语句.它本来是临时的,只是用于处理数据.我很惊讶后来发现声明已经保存并且在SP运行时正在执行.

SET ANSI_NULLS ON
GO

-- Comments usually go here and are saved as part of the SP
ALTER PROCEDURE [dbo].[MySP]
    @param INT
AS
BEGIN
    --Your normal SQL statements here
END

--You can also add SQL statements here
select * from LargeTable

--You have access to the params
select @param
Run Code Online (Sandbox Code Playgroud)

有意义的是保存所有内容,而不仅仅是BEGIN/END内部的内容,否则评论SET ANSI_NULLS等会消失.我对从哪里开始有点困惑,所以我有几个问题:

  1. SET ANSI_NULLS被保存为SP的一部分.我已经确认每个SP都有自己的价值.SQL Server如何知道将其保存为SP的一部分,因为之前没有引用它?它是否对当前环境状态进行全面扫描,然后在ALTER PROCEDURE运行时保存状态(可能只是非默认值)?
  2. 显然BEGIN/END是可选的,没有内在含义.为什么他们甚至包括在内?它们给出了一种不存在的错误范围.在我看来,没有BEGIN/END和最后的GO会最有意义.

bob*_*obs 5

BEGIN...END定义的代码块.它没有定义脚本或过程的开始和结束.但是,我同意这可能令人困惑.

保存SET QUOTED_IDENTIFIER和SET ANSI_NULLS设置,但不保存其他设置.退房互操作性这里了解更多信息.


Phi*_*ley 5

ANSI NULLS和QUOTED IDENTIFIERS存储为存储过程代码的元数据属性.您可以通过查看这些设置

select * from sys.sql_modules 
Run Code Online (Sandbox Code Playgroud)

保存过程时,这些属性将设置为保存过程的连接的任何属性.这可能导致恼人的不一致,所以要小心.

至于BEGIN/END,它与@bobs一样 - 它们表示代码块,它们不表示存储过程代码的开始和结束.(功能,是的,程序,没有.)正如你所说,这no BEGIN/END and a GO at the end would make the most sense是我多年来一直这样做的方式.

从技术上讲,SQL将(尝试)将批处理中的所有内容保存为存储过程的一部分 - 即,您提交的所有文本,由GO语句(如果有)分解.如果您在即席查询之前粘贴了RETURN语句,它们将包含在代码中但从不运行.