《SQL与关系数据库理论——如何编写健壮的SQL代码》一2.7 SQL中的类型检查和型转

简介: 本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第2章 ,第2.7节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

本节书摘来华章计算机《SQL与关系数据库理论——如何编写健壮的SQL代码》一书中的第2章 ,第2.7节 C. J. Date 著 单世民 何英昊 许侃 译 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.7 SQL中的类型检查和型转

SQL只支持弱形式的强类型化(如果你明白我的意思的话)。具体说包括:

  • BOOLEAN值只能赋值到BOOLEAN变量,并只能和BOOLEAN值比较。
  • 数字值只能赋值给数值变量,并且只能与数字值比较(此处的“数字”(numeric)指的是SMALLINT、BIGINT、NUMERIC、DECIMAL 或者FLOAT )。
  • 字符串值只能赋值给字符串变量并且只能与字符串值进行比较(此处的“字符串”指的是CHAR、VARCHAR或者CLOB)
  • 位串值只能赋值给位串变量并且只能和位串值比较(这里的“位串”指的是BINARY 、BINARY VARYING或BLOB )

因此,像数值与字符串这样的比较就是非法的。然而,即使两个数的类型不同,它们之间的比较也是合法的,比如分别属于INTEGER和FLOAT类型的两个数(此时,整型值会在进行比较之前强制型转为FLOAT类型)。这就涉及类型型转问题。在通常的计算领域中,一个广为认可的原则就是要尽量避免型转,因为它们容易出错。尤其是在SQL中,允许型转的一个怪异后果就是某些集合并、交、差运算会产生一些在任何运算元中都没有出现过的行!比如,考虑图2.3中的SQL表T1和T2。假设T1中的X列为INTEGER型,T2表中的X列为NUMERIC(5,1)类型;T1中的Y列为NUMERIC (5,1)类型;T2表中的Y列为INTEGER类型。现在,考虑下面的SQL查询:

SELECT X , Y FROM T1
UNION
SELECT X , Y FROM T2

结果显示在图2.3的最右侧:结果中的X列和Y列都是NUMERIC(5,1)类型,且这些列中的值实际上都由INTEGER型转为NUMERIC(5,1)类型。因此,结果是由未在T1和T2表中出现的行组成的——非常奇怪的并,你要是这么想的话是可以理解的。注17
image

图2.3:很奇怪的“并”
强烈建议:只要可能就尽量避免型转。(我自己的习惯是:无论是在SQL还是其他上下文中,都完全不用它们。)尤其是在SQL上下文中,要确保同名列始终具有同一类型;这个规则以及本书中其他建议,目的是确保能基本避免类型转换。当类型转换无法避免时,建议使用CAST或CAST的等价物进行显式类型转换。比如(对于前述的UNION查询):

SELECT CAST ( X AS NUMERIC(5,1) ) AS X , Y FROM T1
UNION
SELECT X , CAST ( Y AS NUMERIC(5,1) ) AS Y FROM T2

然而,为完整起见我还是要多说一句,某些型转很不幸地内建于SQL之中从而无法回避(我觉得下述说明在这个地方可能没多大用处,但我不想把它们完全忽略):

  • 如果表表达式tx用作行子查询,那么tx所表示的表t就应该只有一行r,将并且表t型转为行r。注意:子查询一词在SQL上下文中随处可见。第12章将详细解释子查询;在其之前,你可以将其不太严谨地看成一个由括号封闭的SELECT表达式。
  • 如果表表达式tx用作标量子查询,那么tx所表示的表应该只有一行一列,因此也只能包含一个值v,并且表t双重型转为值v。注意:此种情况尤其会在SQL风格的聚集计算中出现(参见第7章)。
  • 实践中,在ALL或ANY比较rxsq中的行表达式rx,一般由一个简单的标量表达式构成,此时标量表达式所表示的标量值实际上被型转为只包含此标量值的行。在rxsq中:(a)是后接ALL或ANY的“<”或“>”比较运算符;(b)sq是子查询。注意:在本书中,使用行表达式一词表示行子查询或行选择器调用(行选择器是我对SQL中所谓的行值构建器(row value constructor)的叫法,参见第3章)。换句话说,我使用行表达式(row expression)来表示任何代表一个行的表达式,就像我用表表达式(table expression)来表示任何代表一个表的表达式一样。ALL或ANY比较在第11章中进行详细讨论。

最后,SQL在与字符串相关的极特殊场合也使用术语型转(coercion)。不过,其细节超出了本书范围。

相关文章
|
12天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
52 10
|
29天前
|
SQL 存储 BI
【软件设计师备考 专题 】数据库语言(SQL)
【软件设计师备考 专题 】数据库语言(SQL)
90 0
|
1月前
|
SQL 数据库
sql server中创建数据库和表的语法
sql server中创建数据库和表的语法
18 1
|
12天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
78 6
|
9天前
|
SQL 数据库
数据库SQL语言实战(二)
数据库SQL语言实战(二)
|
9天前
|
SQL 关系型数据库 数据库
【后端面经】【数据库与MySQL】SQL优化:如何发现SQL中的问题?
【4月更文挑战第12天】数据库优化涉及硬件升级、操作系统调整、服务器/引擎优化和SQL优化。SQL优化目标是减少磁盘IO和内存/CPU消耗。`EXPLAIN`命令用于检查SQL执行计划,关注`type`、`possible_keys`、`key`、`rows`和`filtered`字段。设计索引时考虑外键、频繁出现在`where`、`order by`和关联查询中的列,以及区分度高的列。大数据表改结构需谨慎,可能需要停机、低峰期变更或新建表。面试中应准备SQL优化案例,如覆盖索引、优化`order by`、`count`和索引提示。优化分页查询时避免大偏移量,可利用上一批的最大ID进行限制。
34 3
|
12天前
|
SQL 监控 数据库
数据库管理与电脑监控软件:SQL代码优化与实践
本文探讨了如何优化数据库管理和使用电脑监控软件以提升效率。通过SQL代码优化,如使用索引和调整查询语句,能有效提高数据库性能。同时,合理设计数据库结构,如数据表划分和规范化,也能增强管理效率。此外,利用Python脚本自动化收集系统性能数据,并实时提交至网站,可实现对电脑监控的实时性和有效性。这些方法能提升信息系统稳定性和可靠性,满足用户需求。
43 0
|
13天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
20天前
|
数据库 SQL 索引
什么是数据库 SQL Execution Plan
什么是数据库 SQL Execution Plan
11 0
|
28天前
|
SQL 关系型数据库 数据库
OceanBase数据库常见问题之OAT添加服务器预检查的时候报错如何解决
OceanBase 是一款由阿里巴巴集团研发的企业级分布式关系型数据库,它具有高可用、高性能、可水平扩展等特点。以下是OceanBase 数据库使用过程中可能遇到的一些常见问题及其解答的汇总,以帮助用户更好地理解和使用这款数据库产品。

热门文章

最新文章