在存储过程中经常会看到这个 SET ANSI_WARNINGS OFF .那么这个到底起了什么作用呢?
SET的选项中 ANSI_WARNINGS 是什么? 官方的解释
简短总结就是:
ON 对一下几种数据库引擎行为进行ISO判断(该怎么办)
- 在聚合的时候遇到NULL
- 在0作为被除数
- 字符串截位
OFF 引擎遵循非标准行为,这会降低数据质量,并且根据业务上下文可能会生成错误数据。
下面演示这几种情况:
1. 在聚合的时候遇到NULL
SET ANSI_WARNINGS ON
USE tempdb
GO
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
GO
DECLARE @i TABLE (
ID INT NOT NULL IDENTITY(1,1),
DD DATETIME NULL
)
INSERT INTO @i (DD)
SELECT '2017-03-20'
UNION ALL
SELECT NULL
UNION ALL
SELECT '2017-03-19'
UNION ALL
SELECT '2017-03-02'
SELECT MAX(dd) FROM @i;
/*执行结果
2017-03-20 00:00:00.000*/
会生成警告信息
SET ANSI_WARNINGS OFF
这在平常使用中将会产生一些疑惑, 使用COUNT对含有NULL的列进行计数的时候,, 会将NULL消除,
在SET ANSI_WARNINGS 为ON 时才会产生警告,OFF时将没有任何警告.
2. 在0作为被除数
SET ANSI_WARNINGS ON
USE tempdb
GO
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
GO
DECLARE @T TABLE (
ID INT NOT NULL IDENTITY(1,1),
colA DECIMAL(19,4) NULL,
colB DECIMAL(19,4) NULL,
[colA/colB] DECIMAL(19,4) NULL
)
INSERT INTO @T (colA,colB)
VALUES(1.0,2.1),(2.0,3.0),(3.0,0),(4.0,100.0);
UPDATE @T
SET [colA/colB] =colA/colB
SELECT * FROM @T
随之还产生了一个8134的消息
SET ANSI_WARNINGS OFF ,
不会返回结果,将直接产生一个错误.
题外话,如果还想获取不是0为被除数结尾的计算结果该怎么办呢?
(还是有办法的)
SET ARITHABORT OFF
3. 字符串截位
USE tempdb
GO
SET NOCOUNT ON;
SET ANSI_WARNINGS ON;
GO
DECLARE @T TABLE (
ID INT NOT NULL IDENTITY(1,1),
colA VARCHAR(10) NULL,
colB VARCHAR(10) NULL
)
INSERT INTO @T (colA,colB)
VALUES('Tree','oiosdoifooios');
SELECT * FROM @T
SET ANSI_WARNINGS OFF ,
当输入字符串长于其被插入或更新的字段时,输入字符串的静默截断发生。