在开始编写文章前,有几个问题需要思考一下:
* 什么是结构化查询语言
* 结构化查询语言分类
1. 什么是结构化查询语言
SQL 是非过程化语言:只需要知道要做什么,不必担心如何去做。美国国家标准学会(ANSI)制定了一个标准 SQL——最新版本是 SQL-99 或
SQL3。ANSI 的 SQL 标准也被国际标准化组织(ISO),即一个由超过 150 个国家的标准体组成的团体所认可。
SQL 的核心是查询。实际上,在 SQL 中,查询这个词包含了问题和操作两层意思。大多数 SQL 查询用来回答这些问题,如“库存商品中哪些价格超过
$100,这些商品现各有多少?”。然而,许多 SQL 查询用于添加或删除表记录或修改属性值等操作。还有的 SQL 查询创建新的表或索引。
2. 结构化查询语言分类
* 数据定义语言(DDL):SQL 包括创建表、索引和视图等数据库对象命令,以及定义这些数据库对象的访问权限命令。
* 数据操纵语言(DML):定义数据检索和更新。
2.1 数据定义语言
当创建一个新的数据库,RDBMS
会自动创建数据库字典来存储元数据并创建一个默认的数据库管理员。创建保存数据库的物理文件意味着与操作系统以及操作系统支持的文件系统进行交互。
2.1.1 数据库模式
在 SQL
环境中,模式(schema)是一组数据库对象——如表和索引——彼此是相关的。通常,模式属于单个用户或应用程序。一个数据库可以有多个模式,分别属于不同的用户或应用程序。把一个模式看成是一个数据库对象的逻辑分组,如表、索引和视图。模式能有效地将表按照所有者(或功能)分组,并且实施一个一级安全措施,允许每个用户只能看到数据该用户的表。
ANSI SQL 标准定义了一个创建数据库模式的命令:
CREATE SCHEMA AUTHORIZATION {创建者};
大多数企业级的 RDBMS 支持这样的命令。然而,这个命令很少直接使用——在命令行中(当一个用户被创建,DBMS 自动给该用户分配一个模式)。在 DBMS
中,CREATE SCHEMA AUTHORIZATION 命令必须由拥有该模式的用户发布。也就是说,如果用 JONES 身份登录,则只能使用 CREATE
SCHEMA AUTHORIZATION JONES 命令。
注意:MySQL 里没有 create schema 这条语句,而是对应 create database。
2.1.2 创建表结构
使用 CREATE TABLE 命令语法如下:
CREATE TABLE 表名( 列1 数据类型 [约束] [, 列2 数据类型 [约束] ][, PRIMARY KEY (列1 [,列2])][,
FOREGIN KEY (列1 [,列2]) REFERENCES 表名][, CONSTRAINT 约束]);
为了使 SQL 代码更具有可读性,多数 SQL 程序员使用一行代码来定义每一列(属性)。此外,空格用来排列属性的特征和约束。最后,表和属性名全部大写。
注意:[......]:一个可选参数——方括号里面的内容是可选的。
CREATE TABLE VENDOR ( V_CODE INTEGER NOT NULL UNIQUE, V_NAME VARCHAR(3) NOT
NULL, V_CONTANT VARCHAR(15) NOT NULL, V_AREACODE CHAR(3) NOT NULL, V_PHONE
CHAR(8) NOT NULL, V_STARE CHAR(2) NOT NULL, V_ORDER CHAR(1) NOT NULL, PRIMARY
KEY (V_CODE));
PRODUCT 表
CREATE TABLE PRODUCT ( P_CODE VARCHAR(10) NOT NULL UNIQUE, P_DESCRIPT
VARCHAR(35) NOT NULL, P_INDEX DATE NOT NULL, P_QOH SMALLINT NOT NULL, P_MIN
SMALLINT NOT NULL, P_PRICE NUMBER(8,2) NOT NULL, P_DISCOUNT NUMBER(5,2) NOT
NULL, V_CODE INTEGER, PRIMARY KEY (P_CODE), FOREIGN KEY (V_CODE) REFERENCES
VENDOR ON UPDATE CASCADE);
* 属性的 NOT NULL 规范确保一个数据被输入。必须保证数据有效的。NOT NULL
规范将不允许终端用户使属性为空值(根本没有数据输入)。因为在表中提出这个规范并保存在数据字典,所以应用程序可以用这个信息自动创建数据字典合法性。
* UNIQUE 规范在各个属性上创建唯一索引。用它来避免列值重复。
* 主码属性包含 NOT NULL 和 UNIQUE 规范。这些规范确保了实体完整性。如果不支持 NOT NULL 和 UNIQUE 规范,就用
PRIMARY KEY。
* 整个表的定义包含在括号里面。逗号用来隔开表中各个元素(属性、主码和外码)定义
。(如果是复合主码,则主码中所有属性包含在括号里面并用逗号隔开。主码属性的顺序很重要,因为索引从第一个开始,然后是下一个属性。)
* ON UPDATE CASCADE 规范保证,如果修改 VENDOR 的
V_CODE,变化将自动应用到这个系统(级联)所有相关联的外码以确保参照完整性。
表结构的所有修改都可以使用 ALTER TABLE 命令,后面跟着一个你想做的特殊修改的关键字。有 3 种选择:ADD、MODIFY 和 DROP。用
ADD 添加字段,MODIFY 修改字段的特征,DROP 删除字段。大多数 RDBMS
不允许删除字段(除非该字段不包含任何值),因为这种行为可能会删除其他表使用的关键数据。添加或修改字段的基本语法为:
ALTER TABLE 表名 {ADD | MODIFY} (字段名 数据类型[{ADD | MODIFY} 字段 名数据类型]);
ALTER TABLE 命令也可以用来增加表的约束。这种情形下,语法为:
ALTER TABLE 表名 ADD 约束 [ ADD 约束];
也可以用 ALTER TABLE 命令来删除字段或表约束。语法如下:
ALTER TABLE 表名 DROP{PRIMARY KEY | COLUMN 字段名 | CONSTRAINT 约束名};
注意当删除一个约束时,需要指明要删除的约束的名字。这就是为什么应 CREATE TABLE 或 ALTER TABLE 语句中给约束命名的原因。
2.2 数据操纵语言
2.2.1 添加表记录
SQL 使用 INSERT 命令来向表中输入数据,INSERT 命令的基本语法如下:
INSERT INTO 表名 VALUES (值1,值2,...,值n)
如果需要添加多条记录到一个表中,用另外一个表作为数据源。INSERT 语句的语法为:
INSERT INTO 表名 SELECT 字段列表 FROM 表名;
INSERT 语句使用了 SELECT 子查询。子查询,也叫做嵌套查询或内查询,是嵌入(嵌套)在另一个查询中的查询。前面给出的 SQL 语句,INSERT
部分表示外查询,而且 SELECT 部分表示子查询。可以多层嵌套语句(在查询中嵌套查询);在每一层嵌套中,内查询的结果作为外(高一级)查询的输入。
SELECT 子查询返回的值应该匹配 INSERT 语句中表的属性和数据类型。如果插入的表中有一个日期属性、一个数字属性和一个字符属性,则 SELECT
子查询应该返回一行或多行,每行中的第一列有日期值,第二列有数字值,第三列有字符值。
2.2.2 保存表的修改
任何对表内容的修改要等到关闭数据库、关闭使用的程序或使用 COMMIT 命令时才保存到磁盘上。如果在发出 COMMIT
命令之前,数据库打开了后停电或发生一些其他中断,修改的内容将会丢失,只保留原始的表内容。COMMIT 命令的语法是:
commit [工作]
COMMIT 命令会永久保存对数据库中任何表的所有修改内容(如添加的记录、修改的属性值和删除的记录)。因此,如果打算永久保留对 PRODUCT
表的修改,用一下命令来实现是个好方法:COMMIT。
然而,COMMIT 命令不只是为了保存修改内容。实际上,COMMIT 和 ROLLBACK 命令主要用来保证事务管理中的数据库更新完整。
2.2.3 显示表记录
SELECT命令用于显示表的内容。SELECT命令的语法如下:
SELECT 字段列表 FROM 表名;
字段列表表示一个或多个属性,用逗号隔开。可以用 * (星号)作为一个通配符来表示所有属性。通配符是一种符号,用作替代其他字符或命令的一个通用替换符。
尽管 SQL 命令可以写作一行,但是复杂的命令语句最好分行显示,SQL 命令和命令的成员间用空格隔开。这种格式更容易看清 SQL 语句的成员、跟踪 SQL
逻辑,而且如果有必要,便于更正。
通过对输出的记录设置约束,能够选择表的部分内容。可以用 WHERE 子句给 SELECT 语句增加条件约束。下面的语法可以指定选择哪些行:
SELECT 字段列表 FROM 表列表 [WHERE 条件列表 ];
SELECT 语句检索出所有和指定条件匹配的记录——也称为条件判别式——在 WHERE 子句中指定。SELECT 语句的 WHERE
子句中的条件列表由一个或多个条件表达式组成,用逻辑运算符连接。WHERE 子句是可选的。如果没有记录满足 WHERE
子句中的判别式,将看到一个空白屏或一条消息通知你没有检索到记录。
2.2.4 查询结果排序
当显示顺序很重要时,ORDER BY 字句特别有用。语法为:
SELECT 字段列表 FROM 表列表 [WHERE 条件列表] [ORDER BY 字段列表 [ASC | DESC] ];
虽然可以选择排序的类型——升序或降序——默认排序为升序。
2.2.5 显示唯一值
SQL 的 DISTINCT 子句产生一个彼此不相同的值列表。例如,命令:
SELECT DISTINCT V_CODE FROM PRODUCT
2.2.6 数据分组
在 SELECT 语句中使用 GROUP BY 子句可以快速且容易得到频率分布。其语法是:
SELECT 列列表 FROM 表列表 [WHERE 条件列表 ] [GROUP BY 列列表 ] [HAVING 条件列表 ] [ORDER BY 列列表
[ASC | DESC ] ];
当在 SELECT 语句中将属性列和聚集函数结合在一起时,通常都会用到 GROUP BY 子句(只有当和某个 SQL 聚集函数,如
COUNT、MIN、MAX、AVG 和 SUM 一起使用时,GROUP BY 子句才有效。)。
在一个 SELECT 语句中使用 GROUP BY 子句时:
* SELECT 的列列表必须包括一个列名和聚集函数的组合。
* GROUP BY 子句列列表必须包括所有在 SELECT 列列表中指定的非聚集函数列。如果有必要,也可以按 SELECT
的列列表中的任意聚集函数列分组。
* GROUP BY 子句列列表可以包含任何 SELECT 语句的 FROM 子句中的表中任意列,即使这些列不出现在 SELECT 的列列表中。
GROUP BY 用法的一个特殊扩展是 HAVING 子句。HAVING 运算与 SELECT 语句中的 WHERE 子句非常类似。但是,WHERE
子句作用于每一行的列和表达式上,而 HAVING 子句作用于一个 GROUP BY 运算的输出上。
2.3 更新表记录
用 UPDATE 命令修改表中的数据。该命令语法为:
UPDATE 表名 SET 列名 = 表达式 [, 列名 = 表达式] [WHERE 条件列表];
2.4 恢复表的内容
如果还没有 COMMIT 命令在数据库中永久保存修改结果,可以用 ROLLBACK 命令将数据库恢复到以前的状态。ROLLBACK 命令能取消从上次
COMMIT 命令依赖所做的修改操作,将数据恢复到修改前的值。将数据恢复到“修改前”的状态,输入:ROLLBACK;
COMMIT 和 ROLLBACK 命令只能和数据操纵命令添加、修改和删除一起使用。
2.5 删除表记录
用 DELETE 语句很容易删除表中的记录,语法为:
DELETE FROM 表名 [WHERE 条件列表]
2.6 算术运算符:优先级规则
SQL 命令常和以下算术运算符一起使用:
* +:加
* -:减
* *:乘
* /:除
* ^:幂(一些应用程序使用**)
在属性上执行数学运算时,记住优先级规则。正如名字锁表达的意思一样,优先级规则是完成计算的顺序。例如,注意以下计算次序的顺序:
* 执行括号里的运算。
* 执行幂运算。
* 执行乘法和除法运算。
* 执行加法和减法运算。
2.7 逻辑运算符:AND、OR 和 NOT
SQL 允许在一个查询中用逻辑运算符连接多个条件。逻辑运算符包括 AND、OR 和 NOT。
* AND:执行的是并、且操作。
* OR:执行的是或操作。
* NOT:否定一个条件表达式的结果。通常用于查找不匹配一个确定条件的行。
2.8 特殊运算符
ANSI 标准的 SQL 允许将特殊运算符和 WHERE字句一起使用。特殊运算符包括:
* BETWEEN:用于检查属性是否在一个范围内。
* IS NULL:用于检查属性值是否为空。
* LIKE:用于检查属性值是否和指定的字符串匹配。LIKE 和通配符一起用来在字符串属性中查找模式。当不知道完整的字符串时标准 SQL
允许使用百分号(%)和下划线(_)通配符来匹配。% 意味着任何和所有后面和前面的字符是匹配的;_ 意味着任何一个字符可以被下划线替换。
* IN:用于检查属性值是否匹配值列表中的某个值。IN 运算符用了一个值列表。列表中所有值的数据类型必须相同。列表中每个值和属性相比较。
* EXISTS:用于检查子查询是否返回任何记录。
2.9 聚集函数
SQL 可以执行各种数学统计,如计算满足指定条件的行数、查找某个属性上的最小或最大值、计算一列的值之和以及一列的平均值。这些聚集函数如下:
* COUNT:含义非空值的行数。COUNT(*) 聚集函数用于计算一个查询结果集的行数。比较而言,COUNT(column)
聚集函数计算一个指定列中非空值的数量。
* MIN:在给定行中的最小属性值
* MAX:在给定行中的最大属性值
* SUM:给的行中所有值之和
* AVG:给的行中的平均值
2.10 创建视图
一个关系运算符如 SELECT
的输出是另一个关系(或表)。假设在每天结束的时候,要将一份所有商品的清单交个记录员,也就是,现有数量小于或等于最小数量的商品。与其每天结束的时候输入同样的查询,在数据库中永久保存这个查询不是更好吗?这就是视图的功能。视图(view)是建立在
SELECT 查询上的一个虚拟表。查询可以包含来自一个或多个表的列、可计算列、别名和聚集函数。视图建立在它上面的表称为基本表。可以用 CREATE VIEW
命令创建一个视图:
CREATE VIEW 视图名 AS SELECT 查询;
CREATE VIEW 语句是一个数据定义命令,存储子查询规范——SELECT 语句用于产生虚拟表——在数据字典中。
热门工具 换一换