知识卡片
名称限定原则与不可限定的语法上下文
内容
SQL允许在很多场合省略列名的点限定符(如SX.SNO简写成SNO),但省略隐式
限定符会带来两类隐患:一是SQL隐式限定的解析规则本身就不总是直观,一个
未限定名称到底对应哪张表并非总是一目了然;二是即使当前不模糊,未来也可能
变得模糊(比如给已有表新增一列,恰好和另一张参与查询的表同名)——尤其是
如果遵循了[[SQL列命名与位置依赖关系化使用SQL的实践规则]]中”表示同类信息
的列应赋予相同名称”这条建议,未限定名称因此变模糊的概率反而更高。由此得到
一条通用规则:如果存在疑虑,就加限定符。但有一组语法上下文SQL根本不允许
加限定符,因为在这些位置,名称扮演的角色是”对列本身的定义/引用”,而不是
“对列中数据的引用”:基表定义中的列定义、键或外键声明、CREATE VIEW指定的
列名列表、区间变元定义之后指定的列名列表、JOIN...USING里的列名列表、
INSERT语句指定的列名列表、UPDATE的SET赋值左侧。这份清单里最后两项尤其容易
让人踩坑:因为SQL经常把表名本身当区间变元使用([[区间变元的精确定义与相关
名称不是别名的严重误称]]),不熟悉这条边界的用户很容易误以为INSERT/SET
这类上下文里也可以用表名限定列,但这两处恰恰根本没有可供点限定的区间变元
存在。
参考来源
- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第12章"关于SQL的
其他主题"12.3节"名称限定"(源文件:OEBPS/text00136.html)
- 结论依据:原文明确"SQL的规则认为隐式限定总是不容易理解……当前无歧义的
事情在将来可能会模糊……一个很好的通用规则是:如果有疑问,那么就限定。
遗憾的是,有一些上下文并不允许限定……在上述大部分上下文中都没有可用于
点限定的区间变元……没有察觉到此点的用户可能会期望在这些上下文中使用
表名称作为限定符"。
- 原始内容:一个很好的通用规则是:如果有疑问,那么就限定……在上述大部分
上下文中都没有可用于点限定的区间变元……没有察觉到此点的用户可能会期望
在这些上下文中使用表名称作为限定符。