关于计算列
2016-04-06 17:18
204 查看
看到网上有人使用“计算列”(computed coulumn)来强制开发人员禁止SELECT * FROM XXX这种语句的使用。以下是一个简单的例子:
使用SELECT * FROM XXX语句查询,会报错:“Msg 8134, Level 16, State 1, Line 3Divide by zero error encountered.”
![](http://s3.51cto.com/wyfs02/M02/7E/93/wKioL1cE0yjgYaVbAAB8fcZqB54365.jpg)
Figure-1: 运行时报错
而指定字段,则正常运行。
![](http://s5.51cto.com/wyfs02/M01/7E/97/wKiom1cE05nynT9UAAB7Vxf0Y68291.jpg)
Figure-2: 指明字段,运行正常
这种方法的确是可以实现“禁止使用*”的功能,但我个人觉得并不太建议这样做。首先,这本来就是要求开发人员自己主动避免使用*代替所有字段的这个坏习惯,而不应该要求数据库强制报错来避免。第二,如果表的字段很多,在测试或DEBUG时,造成不方便。第三,如果已经运行的系统,还要修改表结构甚至程序,不值得。第四,看到(1/0)这样的逻辑错误,即使最后不会执行,也应该尽量避免吧?如果,万一,我说的是万一……请看下估计执行计划:
![](http://s4.51cto.com/wyfs02/M02/7E/96/wKiom1cE0q_QNm-4AADpPap85bE488.jpg)
Figure-3: Estimated Excution Plan
修改一下计算列,去查看估计执行计划。
![](http://s1.51cto.com/wyfs02/M00/7E/93/wKioL1cE1NiQCEuZAAEEKpnLQCs742.jpg)
Figure-4: Estimated Excution Plan 2都没有报错。为什么呢??
--建表 IF OBJECT_ID(N'T35') IS NOT NULL BEGIN DROP TABLE T35; END; GO CREATE TABLE T35 ( col_1 INT, col_2 AS ( 1 / 0) ) GO --插入数据 INSERT INTO dbo.T35(col_1) VALUES(168); GOCode-1: 创建测试表并插入数据
--查询SELECT * FROM dbo.T35;GOCode-2: 查询
使用SELECT * FROM XXX语句查询,会报错:“Msg 8134, Level 16, State 1, Line 3Divide by zero error encountered.”
![](http://s3.51cto.com/wyfs02/M02/7E/93/wKioL1cE0yjgYaVbAAB8fcZqB54365.jpg)
Figure-1: 运行时报错
而指定字段,则正常运行。
![](http://s5.51cto.com/wyfs02/M01/7E/97/wKiom1cE05nynT9UAAB7Vxf0Y68291.jpg)
Figure-2: 指明字段,运行正常
这种方法的确是可以实现“禁止使用*”的功能,但我个人觉得并不太建议这样做。首先,这本来就是要求开发人员自己主动避免使用*代替所有字段的这个坏习惯,而不应该要求数据库强制报错来避免。第二,如果表的字段很多,在测试或DEBUG时,造成不方便。第三,如果已经运行的系统,还要修改表结构甚至程序,不值得。第四,看到(1/0)这样的逻辑错误,即使最后不会执行,也应该尽量避免吧?如果,万一,我说的是万一……请看下估计执行计划:
![](http://s4.51cto.com/wyfs02/M02/7E/96/wKiom1cE0q_QNm-4AADpPap85bE488.jpg)
Figure-3: Estimated Excution Plan
修改一下计算列,去查看估计执行计划。
--建表 IF OBJECT_ID(N'T35') IS NOT NULL BEGIN DROP TABLE T35; END; GO CREATE TABLE T35 ( col_1 INT, col_2 AS ( col_1 / 0) --修改了这里 ) GO --插入数据 INSERT INTO dbo.T35(col_1) VALUES(168); GOCode-3: 修改表
![](http://s1.51cto.com/wyfs02/M00/7E/93/wKioL1cE1NiQCEuZAAEEKpnLQCs742.jpg)
Figure-4: Estimated Excution Plan 2都没有报错。为什么呢??