《SQL与关系数据库理论——如何编写健壮的SQL代码》一2.9 SQL中的行类型和表类型

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

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

2.9 SQL中的行类型和表类型

再来用一下2.5节“标量类型vs.非标量类型”中定义元组变量的例子:
VAR STV TUPLE { STATUS INTEGER , SNO CHAR , CITY CHAR , SNAME CHAR } ;
你可能还记得,表达式TUPLE{}是对TUPLE类型生成器的调用。SQL有对应的ROW类型生成器(尽管SQL将其命名为类型构造器(type constructor))。下面是一个对前述Tutorial D示例的SQL类比:

DECLARE SRV /* SQL row variable */
        ROW ( SNO        VARCHAR(5) ,
              SNAME  VARCHAR(25) ,
              STATUS INTEGER ,
              CITY   VARCHAR(20) ) ;

然而,与元组不同,SQL中的行对其分量采用自左至右的排序;注19就以此为例,同样的四个分量可以构成24(=4×3×2×1)种不同的行类型(!)。
SQL也支持行赋值。考虑如下Tutorial D元组赋值:

STV := TUPLE FROM ( S WHERE SNO = 'S1' ) ;

下面是类比的SQL行赋值:

SET SRV = ( S WHERE SNO = 'S1' ) ;

右侧表达式是一个行子查询(从语法上讲是一个表表达式,但实际上作为一个行表达式)。这也是SQL中没有什么能显式地对应Tutorial D的TUPLE FROM的原因所在。(参见2.7节“SQL中的类型检查和型转”中对于子查询和型转的讨论)。
在SQL的UPDATE语句(参见第3章)中实际上也涉及了行赋值。.
再来说表。有趣的是,SQL根本没有一个真正的TABLE类型生成器(或像SQL中的类型构造器)!也就是说,SQL没有什么能直接类比于前文中,描述的RELATION类型生成器。然而,它有一个机制(CREATE TABLE)来定义本应被称为TABLE变量的东西。比如,回想一下2.5节“标量类型vs.非标量类型”中的定义:

VAR S BASE
      RELATION { SNO CHAR , SNAME CHAR , STATUS INTEGER , CITY CHAR }
      KEY { SNO } ;

下面是SQL的类比:

CREATE TABLE S
     ( SNO     VARCHAR(5)     NOT NULL ,
       SNAME     VARCHAR(25)     NOT NULL ,
       STATUS     INTEGER     NOT NULL ,
       CITY     VARCHAR(20)     NOT NULL ,
       UNIQUE ( SNO ) ) ;

要小心,本例中没有语言标记序列(sequence of linguistic tokens )能标记为“对TABLE类型构造器的调用”。(在你意识到定义供应商某一完整性的约束UNIQUE(SNO)声明不必列定义,而是几乎可以出现在任何地方(比如,SNO和SNAME列定义之间)之后,这一事实会更加明显。对于单个列定义中同样定义完整性约束的NOT NULL声明就更不必说了。)事实上,在这个意义上可以认为变量S在SQL中具有任何类型,而不管是什么类型它都只不过是“行包”(bag of rows),而当前所讨论行的类型是ROW (S`
NO VARCHAR (5),SNAME VARCHAR (25),STATUS INTEGER ,CITY VARCHAR (20))。

即便如此,我同时应该说明的是:SQL确实支持所谓的“类型化表”(typed tables)。不过,这个词不是很贴切,因为如果TT是一个定义为“T类型”的“类型化表”,那么TT就不是T类型的,并且它的行也不是!更重要的是,你应该尽量避开这样的表,因为它们与SQL对指针(pointer)的支持紧密相关,而指针是在关系模型中被明确禁止的。注20事实上,如果某个表的某列取值是指向另一“目标”表数据行的指针的话,那么这个表就不可能代表关系模型意义下的关系。注21然而,如刚才说的,SQL中不幸地允许此种表存在;指针称为引用值(reference values),包含指针的列则是REF类型(REF type)的。坦白地说,SQL中为什么要包括这些特性完全让人搞不懂;从有用的功能性上来看没什么事是非用它们不可的,事实上不用它们甚至可以做得更好。强烈建议:别用它们以及任何与其相关的特性。
旁注:为了避免可能的混淆,我要说明一下,SQL实际上在两个完全不同的意义下使用术语“参照(referencing)”。一个就像上面描述的那样。另外一个意义(也是更早出现的意义)和外键有关;一行中的一个外键取值被认为是“参照”包含对应目标键值的行。然而要注意,外键可不是指针!——这两个概念之间有多处逻辑差异,尤其是外键指向的是行(也就是行值),而指针是地址,因此按定义指向的是变量。(第1章中提到过,变量是“有空间位置的(have location)”,而值没有空间位置,也没有地址)。

相关文章
|
10天前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:详细步骤与最佳实践指南ali01n.xinmi1009fan.com
随着Web开发技术的不断进步,ASP.NET已成为一种非常流行的Web应用程序开发框架。在ASP.NET项目中,我们经常需要与数据库进行交互,特别是SQL数据库。本文将详细介绍如何在ASP.NET项目中连接SQL数据库,并提供最佳实践指南以确保开发过程的稳定性和效率。一、准备工作在开始之前,请确保您
52 3
|
10天前
|
SQL 监控 数据库
SQL数据库还原详解:步骤、方法与实践指南c1b.0335pw.com
在现代信息技术的浪潮中,数据库管理系统(DBMS)已成为各类组织和企业不可或缺的核心组件。随着数据的不断积累和业务需求的日益增长,数据库的备份与还原成为了确保数据安全与业务连续性的重要手段。本文将深入探讨SQL数据库还原的各个方面,帮助读者理解并掌握数据库还原的核心概念、步骤和方法。一、数据库还原概
|
10天前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
22 10
|
10天前
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
10天前
|
SQL 数据库 数据安全/隐私保护
SQL附加数据库出错的原因与解决方案3w9.0575cst.com
随着信息技术的不断发展,数据库已经成为了各行各业不可或缺的重要组成部分。而SQL作为最流行的数据库管理系统之一,其应用也越来越广泛。但在实际使用中,由于各种原因,我们可能会遇到SQL附加数据库出错的情况。本文将详细介绍SQL附加数据库出错的原因,以及相应的解决方案。一、SQL附加数据库出错的原因1.
|
10天前
|
SQL 存储 关系型数据库
添加数据到数据库的SQL语句详解与实践技巧
在数据库管理中,添加数据是一个基本操作,它涉及到向表中插入新的记录
|
6天前
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
19 0
|
9天前
|
SQL 监控 关系型数据库
SQL错误代码1303解析与处理方法
在SQL编程和数据库管理中,遇到错误代码是常有的事,其中错误代码1303在不同数据库系统中可能代表不同的含义
|
9天前
|
SQL 存储 监控
串口调试助手连接SQL数据库的技巧与方法
串口调试助手是电子工程师和软件开发人员常用的工具,它能够帮助用户进行串口通信的调试和数据分析
|
10天前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:实现过程与关键细节解析an3.021-6232.com
随着互联网技术的快速发展,ASP.NET作为一种广泛使用的服务器端开发技术,其与数据库的交互操作成为了应用开发中的重要环节。本文将详细介绍在ASP.NET中如何连接SQL数据库,包括连接的基本概念、实现步骤、关键代码示例以及常见问题的解决方案。由于篇幅限制,本文不能保证达到完整的2000字,但会确保