(SQL)
查询功能
选择列
使用 SELECT 语句从表中选择特定的列。在该语句中指定用逗号分隔的列名列表。此列表称为选择列表。
下列语句从 SAMPLE 数据库的 ORG 表中选择部门名称 (DEPTNAME) 和部门号 (DEPTNUMB):
SELECT DEPTNAME, DEPTNUMB FROM ORG
上面语句产生下列结果:
DEPTNAME DEPTNUMB -------------- -------- Head Office 10 New England 15
通过使用星号 (*) 可从表中选择所有列。下一个示例列出 ORG 表中的所有的列和行:
SELECT * FROM ORG
此语句产生下列结果:
DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION -------- -------------- ------- ---------- ------------- 10 Head Office 160 Corporate New York 15 New England 50 Eastern Boston
选择行
要从表中选择特定行,在 SELECT 语句之后使用 WHERE 子句指定要选择的行必须满足的条件。从表中选择行的标准是搜索条件。
搜索条件由一个或多个谓词组成。谓词指定关于某一行是真或是假(或未知)的条件。可使用下列基本谓词在 WHERE 子句中指定条件:
|
谓词 |
功能 |
|
x = y |
x 等于 y |
|
x <> y |
x 不等于 y |
|
x < y |
x 小于 y |
|
x > y |
x 大于 y |
|
x <= y |
x 小于或等于 y |
|
x >= y |
x 大于或等于 y |
|
IS NULL/IS NOT NULL |
测试空值 |
在构造搜索条件时,要注意只对数字数据类型执行算术运算,并只在相容数据类型之间进行比较。例如,不能将字符串与数字进行比较。如果正在基于字符值来选择行,则该值必须用单引号括起来(例如,WHERE JOB = 'Clerk'),并且输入的每个字符值必须与数据库中的完全一样。如果数据值在数据库中是小写的,而您用大写形式来输入它,则将不选择行。如果正在基于数字值来选择行,则该值不得用引号括起来(例如,WHERE DEPT = 20)。
下列示例只从 STAFF 表中选择部门 20 的行:
SELECT DEPT, NAME, JOB FROM STAFF WHERE DEPT = 20
此语句产生下列结果:
DEPT NAME JOB ------ --------- ----- 20 Sanders Mgr 20 Pernal Sales 20 James Clerk 20 Sneider Clerk
下一示例使用 AND 来指定多个条件。可以指定任意多个条件。该示例从 STAFF 表中选择部门 20 中的 clerk:
SELECT DEPT, NAME, JOB FROM STAFF WHERE JOB = 'Clerk' AND DEPT = 20
此语句产生下列结果:
DEPT NAME JOB ------ --------- ----- 20 James Clerk 20 Sneider Clerk
未在其中输入值且不支持缺省值的列中出现空值。将值特别设置为空值的地方也可以出现空值。空值只能在定义为支持空值的列中出现。使用谓词 IS NULL 和 IS NOT NULL 来检查空值。
下列语句列出佣金未知的雇员:
SELECT ID, NAME FROM STAFF WHERE COMM IS NULL
此语句产生下列结果:
ID NAME ------ --------- 10 Sanders 30 Marenghi 50 Hanes 100 Plotz 140 Fraye 160 Molinare 210 Lu 240 Daniels 260 Jones 270 Lea 290 Quill
值零与空值不相同。下列语句选择表中佣金为零的每个人:
SELECT ID, NAME FROM STAFF WHERE COMM = 0 因为样本表中的 COMM 列中没有零值,所以返回的结果集为空。
下一个示例选择 STAFF 表中 YEARS 的值大于 9 的所有行:
SELECT NAME, SALARY, YEARS FROM STAFF WHERE YEARS > 9
此语句产生下列结果:
NAME SALARY YEARS --------- --------- ------ Hanes 20659.80 10 Lu 20010.00 10 Jones 21234.00 12 Quill 19818.00 10 Graham 21000.00 13
将行进行排序
您可能想要信息按特定次序返回。使用 ORDER BY 子句将信息按一个或多个列中的值进行排序。下列语句显示部门 84 中按雇用年数排序的雇员:
SELECT NAME, JOB, YEARS FROM STAFF WHERE DEPT = 84 ORDER BY YEARS
此语句产生下列结果:
NAME JOB YEARS --------- ----- ------ Davis Sales 5 Gafney Clerk 5 Edwards Sales 7 Quill Mgr 10
指定 ORDER BY 作为整个 SELECT 语句中的最后一个子句。在此子句中命名的列可以是表达式或表的任何列。ORDER BY 子句中的列名不必在选择列表中指定。
可通过在 ORDER BY 子句中显式指定 ASC 或 DESC 将行按升序或降序进行排序。如果既未指定 ASC,也未指定 DESC,则自动按升序将行进行排序。下列语句按雇用年数以降序显示部门 84 中的雇员:
SELECT NAME, JOB, YEARS FROM STAFF WHERE DEPT = 84 ORDER BY YEARS DESC
此语句产生下列结果:
NAME JOB YEARS --------- ----- ------ Quill Mgr 10 Edwards Sales 7 Davis Sales 5 Gafney Clerk 5
可以按字符值以及数字值将行进行排序。下列语句按姓名字母顺序显示部门 84 的雇员:
SELECT NAME, JOB, YEARS FROM STAFF WHERE DEPT = 84 ORDER BY NAME
此语句产生下列结果:
NAME JOB YEARS --------- ----- ------ Davis Sales 5 Edwards Sales 7 Gafney Clerk 5 Quill Mgr 10
除去重复行
当使用 SELECT 语句时,您可能不想要返回重复信息。例如,STAFF 有一个其中多次列出了几个部门编号的 DEPT 列,以及一个其中多次列出了几个工作说明的 JOB 列。要消除重复行,在 SELECT 子句上使用 DISTINCT 选项。例如,如果将 DISTINCT 插入该语句,则部门中的每项工作仅列出一次:
SELECT DISTINCT DEPT, JOB FROM STAFF WHERE DEPT < 30 ORDER BY DEPT, JOB
此语句产生下列结果:
DEPT JOB ------ ----- 10 Mgr 15 Clerk 15 Mgr 15 Sales 20 Clerk 20 Mgr 20 Sales
DISTINCT 已消除了在 SELECT 语句中指定的一组列中所有包含重复数据的行
运算次序
考虑运算次序是很重要的。一个子句的输出是下一个子句的输入,如下面列表中所示。给表达式命名中给出一个要考虑其中运算次序的示例。并且注意,此说明允许以一种更直观的方式对查询进行考虑。此说明不一定是在内部执行运算的方式。运算顺序如下:
1. FROM 子句
- WHERE 子句
- GROUP BY 子句
- HAVING 子句
- SELECT 子句
使用表达式来计算值
表达式是包括在语句中的计算或函数。下列语句计算,如果部门 38 中每个雇员都收到 $500 的奖金,则每人的薪水将是多少:
SELECT DEPT, NAME, SALARY + 500 FROM STAFF WHERE DEPT = 38 ORDER BY 3
此结果为:
DEPT NAME 3 ------ --------- ---------------- 38 Abrahams 12509.75 38 Naughton 13454.75 38 Quigley 17308.30 38 Marenghi 18006.75 38 O'Brien 18506.00
注意第三列的列名是一个数字。这是一个系统生成的数字,因为 SALARY+500 未指定列名。以后此数字在 ORDER BY 子句中用来表示第三列。可使用基本算术运算符加(+)、减(-)、乘(*)、除(/)来形成算术表达式。
这些运算符可对几种不同类型操作数的值进行运算,其中某些操作数为:
- 列名(例如在 RATE*HOURS 中)
- 常数值(例如在 RATE*1.07 中)
- 标量函数(例如在 LENGTH(NAME) + 1 中)。
给表达式命名
可选的 AS 子句允许您给表达式指定有意义的名称,这就使得以后再引用该表达式更容易。可使用 AS 子句为选择列表中的任何项提供名称。
下列语句显示其薪水加佣金少于 $13,000 的所有雇员。表达式 SALARY + COMM 命名为 PAY:
SELECT NAME, JOB, SALARY + COMM AS PAY FROM STAFF WHERE (SALARY + COMM) < 13000 ORDER BY PAY
此语句产生下列结果:
NAME JOB PAY --------- ----- ---------- Yamaguchi Clerk 10581.50 Burke Clerk 11043.50 Scoutten Clerk 11592.80 Abrahams Clerk 12246.25 Kermisch Clerk 12368.60 Ngan Clerk 12714.80
通过使用 AS 子句,可以在 ORDER BY 子句中引用特定的列名而不是系统生成的数字。在此示例中,我们在 WHERE 子句中将(SALARY + COMM)与 13000 进行比较,而不是使用名称 PAY。这是运算次序的结果。在将(SALARY + COMM)命名为 PAY 之前计算 WHERE 子句的值。因此,不能在该谓词中使用 PAY。
begin
INSERT INTO #temp (sceneId,scenename,userName,addType,topicType,gradeName,pubName)
SELECT D.id,D.scenename,D.userName,D.addType,D.topicType,A.categoryname, b.categoryname
FROM
dbo.T_SituDlg_scene As D,
dbo.T_SituDlg_Category As A,
dbo.T_SituDlg_Category As B,
dbo.T_SituDlg_Category As C
WHERE A.id = B.parentid
AND B.id = C.parentid
AND D.categoryid = C.id
AND B.categoryname='人民教育出版社'
end
从多个表中选择数据
可使用 SELECT 语句从两个或多个表中生成包含信息的报告。这通常称为 连接。例如,可以连接 STAFF 和 ORG 表中的数据以形成一个新表。要连接两个表,在 SELECT 子句中指定想要显示的列,在 FROM 子句中指定表名,在 WHERE 子句中指定搜索条件。WHERE 子句是可选的。
下一个示例使每个经理的姓名与部门名称关联。需要从两个表中选择信息,因为雇员信息(STAFF 表)和部门信息(ORG 表)是独立存储的。下列查询分别选择 STAFF 和 ORG 表的 NAME 和 DEPTNAME 列。搜索条件将选择范围缩小为 MANAGER 列中的值与 ID 列中的值相同的行:
SELECT DEPTNAME, NAME FROM ORG, STAFF WHERE MANAGER = ID
SELECT 语句产生下列结果:
DEPTNAME NAME -------------- --------- Mid Atlantic Sanders South Atlantic Marenghi New England Hanes Great Lakes Plotz Plains Fraye Head Office Molinare Pacific Lea Mountain Quill
该结果列出每个经理的姓名和他或她的部门。
使用子查询
在编写 SELECT 语句时,可在 WHERE 子句中放置另一个 SELECT 语句。每个附加的 SELECT 启动一个子查询。
子查询本身又可包括其值代入其 WHERE 子句的另一个子查询。另外,WHERE 子句可将子查询包括在多个搜索条件中。子查询可引用与主查询中所使用的不同的表和列。
下列语句从 ORG 表中选择 STAFF 表中其 ID 为 280 的雇员的分部和位置:
SELECT DIVISION, LOCATION FROM ORG WHERE DEPTNUMB = (SELECT DEPT FROM STAFFWHERE ID = 280)
在处理此语句时,DB首先确定子查询的结果。结果为 66,因为具有 ID 280 的雇员在部门 66。则最终结果从其部门号列具有值 66 的 ORG 表的行中得出。最终结果是:
DIVISION LOCATION ---------- ------------- Western San Francisco
当使用子查询时,数据库管理程序计算该子查询并将结果值直接代入 WHERE 子句。
使用函数
数据库函数是一组输入数据值和一个结果值之间的关系。
函数可以是内部的或用户定义的。
列函数
列函数对列中的一组值进行运算以得到单个结果值。下列就是一些列函数的示例。有关完整列表,参考 SQL Reference。
AVG
返回某一组中的值除以该组中值的个数的和
COUNT
返回一组行或值中行或值的个数
MAX
返回一组值中的最大值
MIN
返回一组值中的最小值
下列语句从 STAFF 表中选择最高薪水:
SELECT MAX(SALARY) FROM STAFF
此语句从员工 STAFF 样本表中返回值 22959.20。
下一个示例选择其收入超过平均收入但在公司的年数少于平均年数的雇员姓名和薪水。
SELECT NAME, SALARY FROM STAFF WHERE SALARY > (SELECT AVG(SALARY) FROM STAFF) AND YEARS < (SELECT AVG(YEARS) FROM STAFF)
此语句产生下列结果:
NAME SALARY --------- --------- Marenghi 17506.75 Daniels 19260.25 Gonzales 16858.20
在上面示例中的 WHERE 子句中,与直接实现列函数 (WHERE SALARY > AVG(SALARY)) 相反,在子查询中说明列函数。不能在 WHERE 子句中说明列函数。这是由于运算次序的结果。可认为 WHERE 子句是在 SELECT 子句之前进行计算的。因此,当正在计算 WHERE 子句时,列函数没有对该组值的存取权。稍后由 SELECT 子句选择这组值。
可指定 DISTINCT 作为列函数自变量的一部分,以在应用函数之前消除重复值。因此,COUNT(DISTINCT WORKDEPT) 计算不同部门的个数。
标量函数
标量函数对值进行某个运算以返回另一个值。
ABS
返回数的绝对值
HEX
返回值的十六进制表示
LENGTH
返回自变量中的字节数(对于图形字符串则返回双字节字符数。)
YEAR
抽取日期时间值的年份部分
有关标量函数的详细列表和说明,参考 SQL Reference。
下列语句返回 ORG 表中的部门名称以及其每个名称的长度:
SELECT DEPTNAME, LENGTH(DEPTNAME) FROM ORG
此语句产生下列结果:
DEPTNAME 2 -------------- ----------- Head Office 11 New England 11 Mid Atlantic 12 South Atlantic 14 Great Lakes 11 Plains 6 Pacific 7 Mountain 8
注意:由于未使用 AS 子句给 LENGTH(DEPTNAME) 取一个有意义的名称,所以第二列中出现系统生成的数字。
分组
可按照在 GROUP BY 子句中定义的组对行进行分组。以其最简单的形式,组由称为分组列的列组成。 SELECT 子句中的列名必须为分组列或列函数。列函数对于 GROUP BY 子句定义的每个组各返回一个结果。下列示例产生一个列出每个部门编号的最高薪水的结果:
SELECT DEPT, MAX(SALARY) AS MAXIMUM FROM STAFF GROUP BY DEPT
此语句产生下列结果:
DEPT MAXIMUM ------ --------- 10 22959.20 15 20659.80 20 18357.50 38 18006.00 42 18352.80 51 21150.00 66 21000.00 84 19818.00
注意:计算的是每个部门(由 GROUP BY 子句定义的组)而不是整个公司的 MAX(SALARY)。
将 WHERE 子句与 GROUP BY 子句一起使用
分组查询可以在形成组和计算列函数之前具有消除非限定行的标准 WHERE 子句。必须在GROUP BY 子句之前指定 WHERE 子句。例如:
SELECT WORKDEPT, EDLEVEL, MAX(SALARY) AS MAXIMUM FROM EMPLOYEE WHERE HIREDATE > '1979-01-01' GROUP BY WORKDEPT, EDLEVEL ORDER BY WORKDEPT, EDLEVEL
结果为:
WORKDEPT EDLEVEL MAXIMUM -------- ------- ----------- D11 17 18270.00 D21 15 27380.00 D21 16 36170.00 D21 17 28760.00 E11 12 15340.00 E21 14 26150.00
注意:在 SELECT 语句中指定的每个列名也在 GROUP BY 子句中提到。未在这两个地方提到的列名将产生错误。GROUP BY 子句对 WORKDEPT 和 EDLEVEL 的每个唯一组合各返回一行。
在 GROUP BY 子句之后使用 HAVING 子句
可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。为此,在GROUP BY 子句后面包含一个 HAVING 子句。 HAVING 子句可包含一个或多个用 AND 和 OR 连接的谓词。每个谓词将组特性(如 AVG(SALARY))与下列之一进行比较:
· 该组的另一个特性
例如:
HAVING AVG(SALARY) > 2 * MIN(SALARY)
- 常数
例如:
HAVING AVG(SALARY) > 20000
例如,下列查询寻找雇员数超过 4 的部门的最高和最低薪水:
SELECT WORKDEPT, MAX(SALARY) AS MAXIMUM, MIN(SALARY) AS MINIMUM FROM EMPLOYEE GROUP BY WORKDEPT HAVING COUNT(*) > 4 ORDER BY WORKDEPT
此语句产生下列结果:
WORKDEPT MAXIMUM MINIMUM -------- ----------- ----------- D11 32250.00 18270.00 D21 36170.00 17250.00 E11 29750.00 15340.00
有可能(虽然很少见)查询有 HAVING 子句但没有 GROUP BY 子句。如果 HAVING 条件对整个表为真,则返回选择的结果(该结果必须整个由列函数组成);否则不返回任何行。
UNION 运算符
UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
在下列 UNION 运算符的示例中,查询返回薪水高于 $21,000、有管理责任且工龄少于 8 年的人员的姓名:
(1)
SELECT ID, NAME FROM STAFF WHERE SALARY > 21000
UNION
(2)
SELECT ID, NAME FROM STAFF WHERE JOB='Mgr' AND YEARS < 8
ORDER BY ID
各个查询的结果如下:
(1)
ID NAME ------ --------- 140 Fraye 160 Molinare 260 Jones
(2)
ID NAME ------ --------- 10 Sanders 30 Marenghi 100 Plotz 140 Fraye 160 Molinare 240 Daniels
数据库管理程序组合这两个查询的结果,消除重复行,并按升序返回最终结果。
ID NAME ------ --------- 10 Sanders 30 Marenghi 100 Plotz 140 Fraye 160 Molinare 240 Daniels 260 Jones
如果在带有任何集合运算符的查询中使用 ORDER BY 子句,则必须在最后一个查询之后写该子句。系统对组合的回答集进行排序。如果两个表中的列名不同,则组合的结果表没有相应列的名称。替代地,将这些列按其出现的顺序编号。因此,如果想要对结果表进行排序,则必须在 ORDER BY 子句中指定列号。
使用 IN 谓词
使用 IN 谓词将一个值与其他几个值进行比较。例如:
SELECT NAME FROM STAFF WHERE DEPT IN (20, 15)
此示例相当于:
SELECT NAME FROM STAFFWHERE DEPT = 20 OR DEPT = 15
当子查询返回一组值时,可使用 IN 和 NOT IN 运算符。
例如,下列查询列出负责项目 MA2100 和 OP2012 的雇员的姓:
SELECT LASTNAME FROM EMPLOYEE WHERE EMPNO IN (SELECT RESPEMP FROM PROJECT WHERE PROJNO = 'MA2100' OR PROJNO = 'OP2012')
计算一次子查询,并将结果列表直接代入外层查询。例如,上面的子查询选择雇员编号 10 和 330,对外层查询进行计算,就好象 WHERE 子句如下:
WHERE EMPNO IN (10, 330)
子查询返回的值列表可包含零个、一个或多个值。
使用 BETWEEN 谓词
使用 BETWEEN 谓词将一个值与某个范围内的值进行比较。范围两边的值是包括在内的,并考虑 BETWEEN 谓词中用于比较的两个表达式。
下一示例寻找收入在 $10,000 和 $20,000 之间的雇员的姓名:
SELECT LASTNAME FROM EMPLOYEE WHERE SALARY BETWEEN 10000 AND 20000
这相当于:
SELECT LASTNAME FROM EMPLOYEEWHERE SALARY >= 10000 AND SALARY <= 20000
下一个示例寻找收入少于 $10,000 或超过 $20,000 的雇员的姓名:
SELECT LASTNAME FROM EMPLOYEE
WHERE SALARY NOT BETWEEN 10000 AND 20000
使用 LIKE 谓词
使用 LIKE 谓词搜索具有某些模式的字符串。通过百分号和下划线指定模式。
· 下划线字符(_)表示任何单个字符。
- 百分号(%)表示零或多个字符的字符串。
- 任何其他表示本身的字符。
下列示例选择以字母'S'开头长度为 7 个字母的雇员名:
SELECT NAME FROM STAFFWHERE NAME LIKE 'S_ _ _ _ _ _'
下一个示例选择不以字母'S'开头的雇员名:
SELECT NAME FROM STAFF
WHERE NAME NOT LIKE 'S%'
使用 EXISTS 谓词
可使用子查询来测试满足某个条件的行的存在性。在此情况下,谓词 EXISTS 或 NOT EXISTS 将子查询链接到外层查询。
当用 EXISTS 谓词将子查询链接到外层查询时,该子查询不返回值。相反,如果子查询的回答集包含一个或更多个行,则 EXISTS 谓词为真;如果回答集不包含任何行,则 EXISTS 谓词为假。
通常将 EXISTS 谓词与相关子查询一起使用。下面示例列出当前在项目(PROJECT) 表中没有项的部门:
SELECT DEPTNO, DEPTNAME FROM DEPARTMENT X WHERE NOT EXISTS (SELECT * FROM PROJECT WHERE DEPTNO = X.DEPTNO) ORDER BY DEPTNO
可通过在外层查询的 WHERE 子句中使用 AND 和 OR 将 EXISTS 和 NOT EXISTS 谓词与其他谓词连接起来。
定量谓词
定量谓词将一个值和值的集合进行比较。如果全查询返回多个值,则必须通过附加后缀 ALL、ANY 或 SOME 来修改谓词中的比较运算符。这些后缀确定如何在外层谓词中处理返回的这组值。使用>比较运算符作为示例(下面的注释也适用于其他运算符):
表达式 > ALL (全查询)
如果该表达式大于由全查询返回的每个单值,则该谓词为真。如果全查询未返回值,则该谓词为真。如果指定的关系至少对一个值为假,则结果为假。注意:<>ALL 定量谓词相当于 NOT IN 谓词。
下列示例使用子查询和> ALL 比较来寻找收入超过所有经理的所有雇员的姓名和职业:
SELECT LASTNAME, JOB FROM EMPLOYEEWHERE SALARY > ALL
(SELECT SALARY FROM EMPLOYEE WHERE JOB='MANAGER')
表达式 > ANY (全查询)
如果表达式至少大于由全查询返回的值之一,则该谓词为真。如果全查询未返回值,则该谓词为假。注意:=ANY 定量运算符相当于 IN 谓词。
表达式 > SOME(全查询)
SOME 与 ANY 同义。
有关谓词和运算符的更多信息,参考 SQL Reference。
操作功能
插入数据
当创建新表时,新表不包含任何数据。要将新的行输入表中,使用 INSERT 语句。此语句有两种一般格式:
· 一种格式,使用 VALUES 子句来指定一行或多行的列值。下面三个示例使用此一般格式将数据插入表中。
- 另一种格式,指定全查询而非指定 VALUES 来标识来自包含在其他表和/或视图中的行的列。
全查询是 INSERT 或 CREATE VIEW 语句中所使用的选择语句、或者是跟在谓词后面的选择语句。括在括号中的全查询一般称为子查询。
根据创建表时已选择的缺省选项,对于每个插入的行,为每一列提供一个值或者接受一个缺省值。各种数据类型的缺省值在 SQL Reference 中讨论。
下列语句使用 VALUES 子句将一行数据插入 PERS 表中:
INSERT INTO PERS VALUES (12, 'Harris', 20, 'Sales', 5, 18000, 1000, '1950-1-1')
下列语句使用 VALUES 子句将三行插入其中只有 ID、名称以及工作是已知的 PERS 表中。如果列定义为 NOT NULL 且没有缺省值,则必须为该列指定一个值。 CREATE TABLE 语句中的列定义上的 NOT NULL 子句可以用单词 WITH DEFAULT 扩充。如果某一列定义为 NOT NULL WITH DEFAULT 或常数缺省值(如 WITH DEFAULT 10),并且您未在列列表中指定该列,则缺省值插入至已插入行的该列中。例如,在 CREATE TABLE 语句中,仅为 DEPT 列指定了缺省值并将该值定义为 10。因此,DEPT 设置为 10 而所有其他列都为空。
INSERT INTO PERS (NAME, JOB, ID) VALUES ('Swagerman', 'Prgmr', 500),
('Limoges', 'Prgmr', 510), ('Li', 'Prgmr', 520)
下列语句返回插入的结果:
SELECT * FROM PERS ID NAME DEPT JOB YEARS SALARY COMM BIRTH_DATE ------ --------- ------ ----- ------ --------- --------- ---------- 12 Harris 20 Sales 5 18000.00 1000.00 01/01/1950 500 Swagerman 10 Prgmr - - - - 510 Limoges 10 Prgmr - - - - 520 Li 10 Prgmr - - - -
注意:在此情况下,并未给每个列指定值。空值显示为 -。为此,列名列表的次序和数据类型都必须与 VALUES 子句中提供的值对应。如果省略列名列表(如第一个示例中那样),则 VALUES 之后的数据值列表的次序必须与它们所插入至的表中的列次序相同,值的数目必须等于表中列的数目。
每个值必须与它所插入至的列的数据类型相容。如果某列定义为可空,且未指定该列的值,则将空值赋给插入行中的该列。
下列示例将空值插入 YEARS、COMM 和 BIRTH_DATE 中,因为未给行中的那些列指定值。
INSERT INTO PERS (ID, NAME, JOB, DEPT, SALARY) VALUES (410, 'Perna', 'Sales', 20, 20000)
INSERT 语句的第二种格式对于用来自另一表中行的值填充表非常方便。如所述的那样,指定全查询而非指定 VALUES 以标识来自包含在其他表和/或视图中的行中的列。
下列示例从员工 STAFF 表中选择部门 38 的成员的数据,并将它插入 PERS 表中:
INSERT INTO PERS (ID, NAME, DEPT, JOB, YEARS, SALARY) SELECT ID, NAME, DEPT, JOB, YEARS, SALARY FROM STAFF WHERE DEPT = 38
在此插入之后,下列 SELECT 语句与 INSERT 语句中全查询产生的结果相同。
SELECT ID, NAME, DEPT, JOB, YEARS, SALARY FROM PERS WHERE DEPT = 38
结果为:
ID NAME DEPT JOB YEARS SALARY------ --------- ------ ----- ------ --------- 30 Marenghi 38 Mgr 5 17506.75 40 O'Brien 38 Sales 6 18006.00 60 Quigley 38 Sales - 16808.30 120 Naughton 38 Clerk - 12954.75 180 Abrahams 38 Clerk 3 12009.75
更改数据
使用 UPDATE 语句来更改表中的数据。使用此语句,可以更改满足 WHERE 子句搜索条件的每行中的一列或多列的值。下列示例更新其 ID 为 410 的雇员的信息: UPDATE PERS SET JOB='Prgmr', SALARY = SALARY + 300 WHERE ID = 410
SET 子句指定要更新的列并提供值。
WHERE 子句是可选的,它指定要更新的行。如果省略 WHERE 子句,则数据库管理程序用您提供的值更新表或视图中的每一行。
在此示例中,首先命名表 (PERS),然后指定要更新行的条件。雇员编号 410 的信息已更改:该雇员的工作职位更改为 Prgmr,它的薪水增加了 300$。
可以通过包括应用于两行或更多行的 WHERE 子句来更改多行数据。下列示例给每个销售员的薪水增加 15%:
UPDATE PERS SET SALARY = SALARY * 1.15 WHERE JOB = 'Sales'
删除数据
使用 DELETE 语句,基于在 WHERE 子句中指定的搜索条件从表中删除数据行。下列示例删除其中雇员 ID 为 120 的行:
DELETE FROM PERS WHERE ID = 120
WHERE 子句是可选的,它指定要删除的行。如果省略 WHERE 子句,则数据库管理程序删除表或视图中的所有行。
可以使用 DELETE 语句删除多行。下列示例删除其中雇员部门 (DEPT) 为 20 的所有行:
DELETE FROM PERS WHERE DEPT = 20
当删除某一行时,是除去整行,而不是除去行中的特定列值。
要删除表的定义及其内容,发出 DROP TABLE 语句,如 SQL Reference 中所述。
定义功能
创建表
使用 CREATE TABLE 语句创建自己的表,指定列名和类型以及约束。下列语句创建一个命名为 PERS 的表,该表与 STAFF 表类似,但有一个附加列 BIRTH_DATE 。
CREATE TABLE PERS ( ID SMALLINT NOT NULL, NAME VARCHAR(9), DEPT SMALLINT WITH DEFAULT 10, JOB CHAR(5), YEARS SMALLINT, SALARY DECIMAL(7,2), COMM DECIMAL(7,2), BIRTH_DATE DATE)
此语句创建一个其中无数据的表。如示例中所示,为每一列都指定名称和数据类型。 NOT NULL 是可选的,可以指定它以表示列中不允许有空值。缺省值也是可选的。
可以在 CREATE TABLE 语句中指定许多其他选项,如唯一约束或参考约束。有关所有选项的详情,参见 SQL Reference 中的 CREATE TABLE 语句。
用约束和触发器实施商业规则
在商界,我们的确通常需要确保始终实施某些规则。例如,参与项目的雇员必须被雇用。或者想要某些事件有计划地发生。例如,如果销售员售出一批商品,则应增加其佣金。 唯一约束是禁止在表的一列或多列中出现重复值的规则。 参考完整性约束确保在整个指定的表中数据一致性。 表检查约束是一些条件,它们定义为表定义的一部分,限制一列或多列中使用的值。触发器允许您定义一组操作,这些操作通过对指定的表进行删除、插入或更新操作来执行或触发。触发器可用于写入其他表、修改输入值以及发布警报信息。
第一节提供关键字的概念性概述。接着,通过示例和图表进一步探讨参考完整性、约束以及触发器。
关键字
关键字是可用来标识或存取特定行的一组列。
由不止一列组成的关键字称为组合关键字。在具有组合关键字的表中,组合关键字中各列的排序不受这些列在表中排序的约束。
唯一关键字
唯一关键字被定义为它的任何值都不相同。唯一关键字的列不能包含空值。在执行 INSERT 和 UPDATE 语句期间,数据库管理程序强制执行该约束。一个表可以有多个唯一关键字。唯一关键字是可选的,并且可在 CREATE TABLE 或 ALTER TABLE 语句中定义。
主关键字
主关键字是一种唯一关键字,表定义的一部分。一个表不能有多个主关键字,并且主关键字的列不能包含空值。主关键字是可选的,并且可在 CREATE TABLE 或 ALTER TABLE 语句中定义。
外部关键字
外部关键字在参考约束的定义中指定。一个表可以有零个或多个外部关键字。如果组合外部关键字的值的任何部分为空,则该值为空。外部关键字是可选的,并且可在 CREATE TABLE 语句或 ALTER TABLE 语句中定义。
唯一约束
唯一约束确保关键字的值在表中是唯一的。唯一约束是可选的,并且可以通过使用指定 PRIMARY KEY 或 UNIQUE 子句的 CREATE TABLE 或 ALTER TABLE 语句来定义唯一约束。例如,可在一个表的雇员编号列上定义一个唯一约束,以确保每个雇员有唯一的编号。
参考完整性约束
通过定义唯一约束和外部关键字,可以定义表与表之间的关系,从而实施某些商业规则。唯一关键和外部关键字约束的组合通常称为参考完整性约束。外部关键字所引用的唯一约束称为父关键字。外部关键字表示特定的父关键字,或与特定的父关键字相关。例如,某规则可能规定每个雇员(EMPLOYEE 表)必须属于某现存的部门(DEPARTMENT 表)。因此,将 EMPLOYEE 表中的“部门号”定义为外部关键字,而将 DEPARTMENT 表中的“部门号”定义为主关键字。下列图表提供参考完整性约束的直观说明。
表检查约束
表检查约束指定对于表的每行都要进行判定的条件。可对个别列指定检查约束。可使用 CREATE 或 ALTER TABLE 语句添加检查约束。
下列语句创建具有下列约束的表:
- 部门编号的值必须在范围 10 至 100 内
- 雇员的职务只能为下列之一: "Sales"、"Mgr"或"Clerk"
- 1986 年之前雇用的每个雇员的工资必须超过 $40,500。
CREATE TABLE EMP (ID SMALLINT NOT NULL, NAME VARCHAR(9), DEPT SMALLINT CHECK (DEPT BETWEEN 10 AND 100), JOB CHAR(5) CHECK (JOB IN ('Sales', 'Mgr', 'Clerk')), HIREDATE DATE, SALARY DECIMAL(7,2), COMM DECIMAL(7,2),PRIMARY KEY (ID),
CONSTRAINT YEARSAL CHECK (YEAR(HIREDATE) >= 1986 OR SALARY > 40500) )
仅当条件判定为假时才会违反约束。例如,如果插入行的 DEPT 为空值,则插入继续进行而不出错,尽管 DEPT 的值应该象约束中定义的那样在 10 和 100 之间。
下列语句将一个约束添加至名为 COMP 的 EMPLOYEE 表中,该约束为雇员的总报酬必须超过 $15,000:
ALTER TABLE EMP ADD CONSTRAINT COMP CHECK (SALARY + COMM > 15000)
将检查表中现存的行以确保这些行不违反新约束。可通过使用如下的 SET CONSTRAINTS 语句将此检查延期:
SET CONSTRAINTS FOR EMP OFF ALTER TABLE EMP ADD CONSTRAINT COMP CHECK (SALARY + COMM > 15000) SET CONSTRAINTS FOR EMP IMMEDIATE CHECKED首先使用 SET CONSTRAINTS 语句以延期对表的约束检查。然后可将一个或多个约束添加至表而不检查这些约束。接着再次发出 SET CONSTRAINTS 语句,反过来将约束检查打开并执行任何延期的约束检查。
浙公网安备 33010602011771号