Tsql 存储过程中END之后的语句
今天我遇到了一个有趣的问题。我正在修改一个存储过程,并在最后放了一个select语句。这是暂时的,只是为了处理数据。后来我惊讶地发现,该语句被保存,并在SP运行时执行Tsql 存储过程中END之后的语句,tsql,stored-procedures,Tsql,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 statement
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
保存所有内容是有意义的,而不仅仅是BEGIN/END中的内容,否则注释和SET ANSI_NULLS
等将消失。我对从哪里开始有点困惑,所以我有几个问题:
SET ANSI_NULLS
保存为SP的一部分。我已确认每个SP都有自己的值。SQL Server如何知道将其保存为SP的一部分,因为它以前未被引用?它是否对当前环境状态进行完整扫描,然后在运行ALTER PROCEDURE
时保存状态(可能只有非默认值)BEGIN…END
定义了一个代码块。它不定义脚本或过程的开始和结束。但是,我同意这可能令人困惑
将保存SET QUOTED_标识符和SET ANSI_NULLS设置,但不保存其他设置。查看互操作性以了解更多信息。ANSI NULL和带引号的标识符存储为存储过程代码的元数据属性。您可以通过查看这些设置
select * from sys.sql_modules
保存过程时,这些属性将设置为保存过程所通过的连接的任何属性。这会导致令人恼火的矛盾,所以要小心
至于BEGIN/END,正如@bobs所说的——它们表示代码块,而不是表示存储过程代码的开始和结束。(函数,是的,过程,否)正如你所说,不开始/结束,在结束时进行操作最有意义
是我多年来一直采用的方式
从技术上讲,SQL将(尝试)将批处理中的所有内容保存为存储过程的一部分,也就是说,您提交的所有文本都将被GO语句(如果有的话)分解。如果在临时查询之前插入了RETURN语句,它们将包含在代码中,但永远不会运行
包含一系列Transact-SQL
语句使一组
Transact-SQL语句可以是
执行<代码>开始和结束
是
控制流语言关键字
当SET ANSI_NULLS
为ON
时,使用WHERE
column_name=NULL
的SELECT
语句返回零行,即使column_name中存在空值。使用WHERE
column\u nameNULL
的SELECT
语句返回零行,即使column\u name中存在非NULL值
当SET ANSI_NULLS
处于禁用状态时,等于(=)和不等于()比较运算符不符合ISO标准。使用WHERE column\u name=NULL的SELECT
语句返回列\u name中具有NULL值的行。使用WHERE
column\u nameNULL
的SELECT
语句返回列中具有非NULL值的行。另外,使用WHERE
column\u name XYZ\u value的SELECT语句将返回所有非XYZ\u值且非NULL的行
当SET ANSI_NULLS
为ON
时,与空值的所有比较计算为未知。当SET ANSI_NULLS
为OFF
时,如果数据值为空,则所有数据与空值的比较将计算为TRUE。如果未指定SET ANSI_NULLS
,则当前数据库的ANSI_NULLS
选项的设置适用。有关ANSI_NULLS
数据库选项的详细信息,请参阅ALTER database
(Transact-SQL)和设置数据库选项
SET ANSI_NULLS ON
仅当比较的一个操作数是NULL
变量或文本NULL
时,才会影响比较。如果比较的两侧都是列或复合表达式,则该设置不会影响比较
要使脚本按预期工作,无论ANSI_NULLS
数据库选项或SET ANSI_NULLS
的设置如何,在可能包含空值的比较中使用ISNULL
和IS NOT NULL
SET ANSI_NULLS
应设置为ON以执行分布式查询
在计算列或索引视图上创建或更改索引时,“设置ANSI_NULLS”也必须启用。如果SET ANSI_NULLS
为OFF
,则在计算列或索引视图上具有索引的表上的任何创建
、更新
、插入
和删除
语句都将失败。SQL Server将返回一个错误,其中列出了所有违反所需值的设置选项。此外,当执行SELECT
语句时,如果SET ANSI_NULLS
为OFF
,SQL Server将忽略计算列或视图上的索引值,并解析SELECT操作,就好像表或视图上没有此类索引一样。BEGIN/END用于作用域,就像在IF/WHILE/etc中包含多个语句一样。坦率地说,与PLSQL相比,TSQL的使用非常糟糕——PLSQL在使用BEGIN/END和使用分号终止行的方式上更加结构化/组织化。就像TSQL在WITH/CTE之前声明变量时要求在WITH/CTE之前使用分号一样…:/C语言经验的任何人都可以使用PLSQL并能够读取它。对于TSQL不能这么说…@OMG-那么在这种情况下它给出了什么“范围”?我唯一能想象的是如果你申报