SET ANSI_WARNINGS OFF 干了点儿啥?
在存储过程中经常会看到这个 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 ,
当输入字符串长于其被插入或更新的字段时,输入字符串的静默截断发生。