实用SQL语言
1.概述
SQL(Structured Query Language)即为结构化查询语言,它的主要功能就是同各种数据库建立联系,进行沟通。按照ANSI(美国国家标准协会)的规定,Transact-SQL被作为关系型数据库管理系统的标准语言。目前,绝大多数流行的关系型数据库管理系统,如Oracle, Sybase, Microsoft SQL Server, Access等都采用了SQL语言标准。虽然很多数据库都对SQL语句进行了再开发和扩展,但是包括Select, Insert, Update, Delete, Create, 以及Drop在内的标准的SQL命令仍然可以被用来完成几乎所有的数据库操作。
SQL由四部分组成:
· 数据定义语言(DDL,Data Definition Language):定义SQL模式,基本表、视图和索引。
· 数据操纵语言(DML,Data Manipulation Language):包括数据查询和数据更新(增、删、改)。
· 数据控制语言(DCL,Data Control Language):包括对基本表和视图的授权、完整性规则的描述,事务控制等。
·
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
控制语言(PCL,Process Control Language):控制SQL语句流程。
下面,我们就来详细介绍一下SQL语言的基本知识
2.数据定义语言(DDL)
2.1SQL模式的创建和撤消
SQL模式的创建可简单理解为建立一个数据库,定义一个存储空间,其句法是:
CREAT SCHEMA <模式名> AUTHORIZATION <用户名>
注:AUTHORIZATION表示授权给某用户
撤消SQL模式的句法为:
DROP SCHEMA <模式名> [ CASCADE | RESTRICT ]
注:方括号中的选项参数CASCADE表示连锁方式,执行时将模式下所有基本表、视图、索引等元素全部撤消;RESTRICT表示约束式,执行时必须在SQL模式中没有任何下属元素时方可撤消模式。
2.2SQL提供的基本数据类型
· 数值型:包括 integer、smallint、real、double precision 、float(n)、numeric(p[,d])。
· 字符串型:char(n)、varchar(n),前者是定长,后者为变长串。
· 位串型:bit(n),bit varying(n),同上。
· 时间型:date、time。
注:该数据类型为基本数据类型,根据不同的DBMS有不同的定义和扩展;具体数据类型说明请参考具体数据库系统的数据类型说明。
2.3基本表的创建、修改和撤消
基本表的创建:(可理解为建立表结构)
CREAT TABLE SQL 模式名.基本表名
(列名,类型,
……
完整性约束...)
注:完整性约束包括主键子句(PRIMARY KEY)、检查子句(CHECK)和外键子句(Foreign KEY)。
基本表结构的修改:
ALTER TABLE 基本表名 ADD/ DROP (增加/删除) 列名 类型名(增加时写出)
基本表的撤消:
DROP TABLE 基本表名 [CASCADE|RESTRICT]
注:删除时有子句 [CASCADE|RESTRICT],前者为连锁删除,后者为约束删除,即没有对本列的任何引用时才能删除。
2.4视图的创建和撤消
视图的创建:
CREAT VIEW 视图名(列名表) AS SELECT 查询语句
视图的撤消:
DROP VIEW 视图名
2.5索引的创建和撤消
索引的创建:
CREAT [UNIQUE] INDEX 索引名 ON 基本表名(列名表 [ASC|DESC])
索引的撤消:
DROP INDEX 索引名
注:凡创建都用CREATE,删除都用DROP,改变用Alter,再跟类型和名字,附加子句很容易了。
3.数据操纵语言(DML)
3.1数据查询语句
数据查询语句即为Select语句,用于检索数据。这是我们在编程中最常用的语句,也是本教程的重点所在。
在介绍查询语句之前,我们先定义三个表,以供示例使用:
· 供应商表(t_supplier):存储供应商编号(f_sid),名称(f_sname)和产地(f_city)的表。
· 零件表(t_part)是存储零件的编号(f_pid)名称(f_pname)和价格(f_price)的表。
· 销售表(t_sells)存储关于某个供应商(f_sid)销售的零件(f_pid)的信息。它是联接其他两个表的结点。
现有数据:
t_supplier:
f_sid
f_sname
f_city
1
Smith
London
2
Jones
Paris
3
Adams
Rome
4
Blake
Peking
5
Zyx
Jinan
t_part:
f_pid
f_pname
f_price
1
Screw
2
Nut
8
3
Bolt
15
4
Gear
25
5
Ball
5
t_sells:
f_id
f_date
f_sid
f_pid
f_count
1
2006-01-01
1
1
10
2
2006-01-02
1
2
15
3
2006-01-03
2
4
5
4
2006-01-04
3
1
100
5
2006-01-05
3
3
50
6
2006-01-06
4
2
23
7
2006-01-07
4
3
78
8
2006-01-08
4
4
110
3.1.1 Select语句语法
SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] [TOP integer]* | expression [ AS output_name ] [, ...]
[ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION | INTERSECT | EXCEPT [ ALL ] } select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
SQL语言提供了丰富而强大的数据查询功能,下面让我们从不同的例子中体会SELECT语句强大的查询统计功能。
3.1.2从一个简单的查询开始
1)首先我们做一个使用SELECT语句的简单例子:带有条件的简单查询
要求:要从零件表里面把价格大于10的所有记录找出来
语句:select * from t_part where f_price > 10
结果集:
f_pid | f_pname | f_price
3 Bolt 15
4 Gear 25
(2 rows)
2)根据要求,我们对上一个Select语句作一下改动
要求:只希望从零件表中检索出零件的名称和价格
语句:select f_pname,f_price from t_part where f_price > 10
结果集:
f_pname | f_price
Bolt 15
Gear 25
(2 rows)
3)对于多个不同的条件,可在WHERE子句中使用关键字OR,AND,和NOT逻辑地联接起来:
要求:从零件表中检索出名称为Bolt并且价格为20或不大于15的零件的名称与价格
语句:selete f_pname,f_price from t_part where f_name = 'Bolt' and (f_price = 20 or f_price <=15)
结果集:
f_pname | f_price
Bolt 15
(1 rows)
4)目标列表和WHERE子句里可以使用算术操作。
要求:我们想买两个同样的零件,但我们只有25块钱,查询出我们能够买到的零件以及需要花的钱数
语句:select f_pname,f_price*2 as f_double from t_part where f_price*2 < =25
结果集:
f_pname | f_double
Screw 20
Nut 16
(2 rows)
注:在关键字 AS 后面的double是第二个列的新名字。 这个技巧可以用于目标列表里的每个元素, 给它们赋予一个在结果列中显示的新的标
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
。 这个新的标题通常称为别名。这个别名不能在该查询的其他地方使用。
3.1.3联接
3.1.3.1普通联接
表与表之间通过字段相等或不等关联的方式进行联接是最为普通的联接方式,让我们看下面的例子:
要求:我们要查询处每天销售的零件名称、价格以及零件的供应向及其所处城市
语句:select f_date,f_pname,f_price,f_sname,f_city
from t_sells as SE,t_supplier as SU,t_part as PA
where SE.f_sid=SU.f_sid and SE.f_pid=PA.f_pid.
结果集:
f_date | f_pname | f_price | f_sname | f_city
2006-01-01 Screw
10
Smith
London
2006-01-02 Nut
8
Smith
London
2006-01-03 Gear
25
Jones
Paris
2006-01-04 Screw
10
Adams
Rome
2006-01-05 Bolt
15
Adams
Rome
2006-01-06 Nut 8
Blake
Peking
2006-01-07 Bolt
15
Blake
Peking
2006-01-08 Gear
25
Blake
Peking
(8 rows)
注:在WHERE子句中,我们在属性列名前加"表名. "以区分不同表的公共命名属性(f_sid和f_pid)。
普通联接(联合)的计算方法是这样的:首先算出笛卡儿积t_supplier×t_part×t_sells,然后选出那些满足WHERE子句里给出的条件的记录(也就是说,公共命名属性的值必须相等),最后我们映射出除f_date,f_pname,f_price,f_sname,f_city这些属性。
另外,关于别名运算符AS,我们要注意以下两点:
· 对于长度较短的表名以及不会产生混淆的字段名尽量不用别名,因为别名总是没有原名更具有表述性。
· 别名尽量简洁和富于表述,这样我们在使用时能更好的识别它。
除了上面的这种方式,我们实现普通联接还可以采用下面这样的SQL JOIN语法:
语句:select f_date,f_pname,f_price,f_sname,f_city
from t_sells
join t_supplier on (t_sells.f_sid=t_supplier.f_sid)
join t_part on (t_sells.f_pid=t_part.f_pid)
结果集:
f_date | f_pname | f_price | f_sname | f_city
2006-01-01 Screw
10
Smith
London
2006-01-02 Nut
8
Smith
London
2006-01-03 Gear
25
Jones
Paris
2006-01-04 Screw
10
Adams
Rome
2006-01-05 Bolt
15
Adams
Rome
2006-01-06 Nut 8
Blake
Peking
2006-01-07 Bolt
15
Blake
Peking
2006-01-08 Gear
25
Blake
Peking
(8 rows)
SQL JOIN有两种主要类型:CROSS JOIN (无条件联接) 和条件联接,下面我们详细讨论一下这两类联接方式。
3.1.3.2无条件联接(CROSS JOIN)
语句格式:
{ T1 } CROSS JOIN { T2 }
说明:一个交叉联接(CROSS JOIN)接收两个分别有N行和M行的表T1和T2,然后返回一个包含交叉乘积 N×M 条记录的联接表;显然交叉联接生成的是表的笛卡尔积。
CROSS JOIN实际上就是一个INNER JOIN ON TRUE.
要求:我们想知道零件和供应商有多少可能的组合
语句:select * from t_part cross join t_supplier
结果集:
f_pid | f_pname | f_price | f_sid | f_sname | f_city
1 Screw
10
1
Smith London
2 Nut
8
1
Smith London
3 Bolt 15
1
Smith London
4 Gear
25
1
Smith London
1 Screw 10
2
Jones Paris
2 Nut
8
2
Jones Paris
3 Bolt
15
2
Jones Paris
4 Gear
25
2
Jones Paris
1 Screw
10
3
Adams
Rome
2 Nut
8
3
Adams
Rome
3 Bolt
15
3
Adams
Rome
4 Gear
25
3
Adams
Rome
1 Screw
10
4
Blake
Peking
2 Nut
8
4
Blake
Peking
3 Bolt
15
4
Blake
Peking
4 Gear
25
4
Blake
Peking
(16 rows)
3.1.2.3条件联接(join)
语句格式:
{ T1 } [ NATURAL ] [ INNER | { LEFT | RIGHT | FULL } [ OUTER ] ] JOIN { T2 } { ON search condition | USING ( join column list ) }
说明:一个条件JOIN必须通过提供一个(并且只能有一个) NATURAL,ON或者USING这样的关键字来声明它的联接条件。
· ON子句接受一个查询条件(search condition),它与WHER子句的功能相同;
· USING子句接受一个用逗号分隔的字段名列表,联接表中必须都有这些字段,并且用那些字段联接这些表,生成的联接表包含每个共有字段和两个表的所有其它字段;
· NATURAL是USING子句的缩写,它列出两个表中所有公共的字段名字.使用USING和NATURAL的副作用是每个联接的字段都只有一份拷贝出现在结果表中(与前面定义的关系演算的JOIN相比较);
对于所有JOIN而言,INNER和OUTER都是可选的。INNER是缺省,LEFT,RIGHT,和FULL 只用于OUTER JOIN.
备注:这里我们对USING和NATURAL做一般了解即可,我们主要讨论ON子句的使用。
3.1.2.3.1[ INNER ] JOIN
内联接仅显示两个联接表中的匹配行的联接,是默认联接类型,其效果与普通联接相同,即T1 JOIN T2相当于T1 INNER JOIN T2。例如我们可以联接t_part表和t_sells表以创建显示零件销售情况的结果集,在内联接中,结果集内不包含没有销售记录的零件,也不包含没有零件名的销售记录。
语句:select f_id,f_date,f_pname from t_part inner join t_sells on t_part.f_pid=t_sells.f_pid
结果集:
f_id | f_date | f_pname
1 2006-01-01
Screw
2 2006-01-02
Nut
3 2006-01-03
Gear
4 2006-01-04
Screw
5 2006-01-05
Bolt
6 2006-01-06
Nut
7 2006-01-07
Bolt
8 2006-01-08
Gear
(8 rows)
注:当创建内联接时,包含NULL的列不与任何值匹配,因此不包括在结果集内。空值不与其它的空值匹配。
3.1.2.3.2 OUTER JOIN
3.1.2.3.2.1LEFT [ OUTER ] JOIN
对于左外连接(LEFT [OUTER] JOIN):首先,执行一次INNER JOIN;然后,如果T1里有一行对任何 T2 的行都不满足联接条件,那么返回一个联接行,该行的 T2 的字段为空(null)。我们可以简单的理解为:LEFT [OUTER] JOIN联接成的表无条件地包含T1(JOIN左边的表)里的所有行。
要求:统计5个供应商各自的销售记录
语句:select f_sname,f_city,f_id,f_date from t_supplier left join t_sells on t_supplier.f_sid=t_sells.f_sid
结果集:
f_sname | f_city | f_id | f_date
Smith London
1
2006-01-01
Smith London
2
2006-01-02
Jones Paris 3
2006-01-03
Adams Rome
4
2006-01-04
Adams Rome
5
2006-01-05
Blake Peking
6
2006-01-06
Blake Peking
7
2006-01-07
Blake Peking
8
2006-01-08
Zyx Jinan
NULL
NULL
(9 rows)
3.1.2.3.2.2RIGHT [ OUTER ] JOIN
我们参照LEFT [OUTER] JOIN来理解RIGHT [OUTER] JOIN。
对于右外连接(RIGHT [OUTER] JOIN):首先,执行一次INNER JOIN;然后,如果T2里有一行对任何 T1 的行都不满足联接条件,那么返回一个联接行,该行的 T1 的字段为空(null)。我们可以简单的理解为:RIGHT [OUTER] JOIN联接成的表无条件地包含T2(JOIN右边的表)里的所有行。
对于上面的例子,同样我们用RIGHT [OUTER] JOIN可以写成下面的语句:
select f_sname,f_city,f_id,f_date from t_sells right join t_supplier on t_sells.f_sid=t_supplier.f_sid
3.1.2.3.2.3FULL [ OUTER ] JOIN
对于完整外连接(FULL [OUTER] JOIN):首先,执行一次INNER JOIN;然后,如果T1里有一行对任何 T2 的行都不满足联接条件,那么返回一个联接行,该行的 T2 的字段为空(null);再然后,如果T2里有一行对任何 T1 的行都不满足联接条件,那么返回一个联接行,该行的 T1 的字段为空(null)。我们可以简单的理解为:FULL [OUTER] JOIN 相当于LEFT [OUTER] JOIN和RIGHT [OUTER] JOIN查询的结果集再通过UNION(不是UNION ALL)连接在一起。
这里我们就不举例子了,请同学们参考前两个例子来理解完整外连接。
小结:JOIN是我们使用频率非常高的SQL语句,请大家认真体会;另外,对于JOIN,我们再补充以下几点:
· 所有类型的JOIN都可以链接在一起或者嵌套在一起, 这时T1和T2都可以是联接生成的表。我们可以使用圆括弧控制JOIN的顺序,如果我们不主动控制,那么联接顺序是从左到右。
· 当组合多个表的数据时,必须决定把什么表放在FROM子句,把什么表放在ON子句中。比如,我们要查询各个供应商及零件的销售情况,这时销售表(t_sells)处于零件表(t_part)和供应商表(t_supplier)之间的位置,因此我们将销售表(t_sells)放在FROM子句,以销售表(t_sells)为基础,建立其与零件表(t_part)和供应商表(t_supplier)之间的联系,这样结构更加清晰一些。
3.1.4聚集
3.1.4.1聚集操作符
SQL提供以一些聚集操作符(如:AVG,COUNT,SUM,MIN,MAX),这些聚集操作符以一个表达式为参数,只要是满足WHERE 子句的行,就会计算这个表达式,然后聚集操作符对这个输入数值的集合进行计算。
通常,一个聚集对整个 SELECT 语句计算的结果是生成一个结果。但如果在一个查询里面声明了分组, 那么数据库将对每个组进行一次独立的计算,并且聚集结果是按照各个组出现的(见下节)。
下面我们先看两个简单使用聚集操作符的SQL语句的例子:
要求:我们想知道零件表(t_part)里面所有零件的平均价格
语句:select avg(f_price) as avg_price from t_part
结果集:
avg_price
14
(1 rows)
要求:我们想知道零件表(t_part)里面有多少种类的零件
语句:select count(f_pid) as count_part from t_part
结果集:
count_part
4
(1 rows)
3.1.4.2分组聚集
SQL允许我们把一个表里面的记录分成组,那么上面描述的聚集操作符可以应用于这些组上。也就是说,聚集操作符的值不再是对所有声明的列的值进行操作,而是对一个组的所有值进行操作。这样聚集函数是为每个组独立地进行计算的。
对记录的分组是通过关键字GROUP BY实现的,GROUP BY 后面跟着一个定义组的构成的属性列表。 如果我们使用语句 GROUP BY F1,F2,F3,我们就把关系分成了组;这样当且仅当两条记录在所有属性F1,F2,F3上达成一致,它们才是同一组的。
下面我们做个例子来理解分组聚集:
要求:我们想知道每个供应商销售多少个零件
语句:select t_sells.f_sid,f_sname,sum(f_count) as part_count
from t_sells,t_supplier
where t_sells.f_sid=t_supplier.f_sid
Group by t_sells.f_sid,f_sname
Order by t_sells.f_sid
结果集:
f_sid | f_sname | part_count
1 Smith
25
2 Jones
5
3 Adams
150
4 Blake
211
(4 rows)
下面我们来分析一下,这条SQL语句是如何执行的:
首先,按照连接条件生成表t_sells和t_ supplier 的联接:
f_sid | f_sname | f_count
1 Smith
10
1 Smith
15
2 Jones
5
3 Adams
100
3 Adams
50
4 Blake
23
4 Blake
78
4 Blake
110
(8 rows)
然后,我们把那些属性f_sid,f_sname相同的记录放在组中:
f_sid | f_sname | f_count
1 Smith
10
15
2 Jones
5
3 Adams
100
50
4 Blake
23
78
110
在我们的例子里,我们有四个组并且现在我们可以对每个组应用聚集操作符SUM,生成上面给出的查询的最终结果。
f_sid | f_sname | part_count
1 Smith
25
2 Jones
5
3 Adams
150
4 Blake
211
(4 rows)
注:如果要让一个使用GROUP BY和聚集操作符的查询的结果有意义, 那么用于分组的属性(GROUP BY 子句中的列名)可以出现在目标列表(SELECT子句中的列名)中。所有没有在GROUP BY子句里面出现的属性都只能通过使用聚集函数来选择,否则就不会有唯一的数值与其它字段关联。
还要注意的是在聚集上聚集是没有意义的,比如:AVG(MAX(f_sid)), 因为SELECT只做一个回合的分组和聚集。如果你想获得这样的结果, 可以使用临时表或者在FROM子句中使用一个子查询做第一个层次的聚集。
3.1.5Having子句
HAVING子句主要用于聚集查询中,从功能上讲常象WHERE子句,只对那些满足HAVING子句里面给出的条件的组进行计算。它们的区别在于, WHERE在分组和聚集之前过滤掉不符合条件的记录,而 HAVING则是在GROUP之后过滤掉那些不符合条件的组。因此,WHERE无法使用一个聚集函数的结果。而另一方面,我们也没有理由写一个不涉及聚集函数的HAVING子句;如果在你的条件中不包含聚集,那么你完全可以把它写在WHERE子句里面, 这样就可以避免对那些你准备抛弃的记录进行聚集运算。
我们来看一个例子。
要求:统计销售超过一种零件的供应商编号、名称及其销售零件的种数
语句:select t_supplier.f_sid,t_supplier.f_sname,count(t_sells.f_pid) as sell_count
from t_sells,t_supplier
where t_sells.f_sid=t_supplier.f_sid
group by t_supplier.f_sid,t_supplier.f_sname
having count(t_sells.f_pid)>1
order by t_supplier.f_sid
结果集:
f_sid | f_sname | sell_count
1 Smith
2
3 Adams
2
4 Blake
3
(4 rows)
注:HAVING子句应紧跟在GROUP BY后面,在这个例子中如果我们将HAVING子句放在ORDER BY子句之后,就会报错。
3.1.6子查询
子查询亦称子选择,它和普通查询一样,都产生一个结果集/值,当我们需要一个中间结果集/值时,我们就需要使用子查询。可以想象,子查询的使用能够大大扩展SQL的表达能力。
3.1.6.1WHERE与HAVING子句中的子查询
在WHERE和HAVING子句里,允许在任何要产生数值的地方使用子查询。这种情况下,该数值必须首先来自对子查询的计算。
我们来看下面的例子。
要求:统计出所有比名为 'Screw' 的零件贵的零件
语句:select * from t_part
where f_price>(select f_price from t_part where f_pname='Screw')
结果集:
f_pid | f_pname | f_price
3 Bolt
15
4 Gear
25
(2 rows)
说明:当我们检查上面的查询时会发现出现了两次SELECT关键字。第一个在查询的开头,我们将之称之为外层SELECT;而另一个在WHERE子句里面,成为一个嵌入的查询,我们将称之为内层SELECT。 对外层SELECT的每条记录都必须先计算内层SELECT。在完成所有计算之后,我们得知名为 'Screw' 零件的记录的价格, 然后我们就可以检查那些价格更贵的记录了。 (实际上,在本例中,内层查询只需要执行一次, 因为它不依赖于外层查询。)
我们再来看另一个例子。
要求:统计哪些不销售任何零件的供应商 (比如说,我们想把这些供应商从数据库中删除)
语句:select * from t_supplier
where not exists
(select * from t_sells where t_sells.f_sid=t_supplier.f_sid)
结果集:
f_sid | f_sname | f_city
5 Zyx
Jinan
(1 rows)
注:我们在WHERE子句的内层SELECT里使用了来自外层SELECT的t_supplier.f_sid。 正如前面所说的,子查询为每个外层查询计算一次,也就是说,S.SNO的值总是从外层SELECT的实际记录中取得的。
3.1.6.2在FROM里面的子查询
当我们把子查询看作是一个结果集时,那么它就相当于一个普通的表,因此,在FROM子句我们同样可以使用子查询。这个特性很有用,FROM里的子查询还可以让我们获得多于一个回合的分组/聚集特性,而不需要求助于临时表。
我们通过下面的例子来理解这一点。
要求:查询出所有供应商中的最高的平均零件价格
语句:select max(subtable.avg_price) as avgPrice
from (select avg(f_price) as avg_price
from t_sells,t_supplier,t_part
where t_sells.f_sid=t_supplier.f_sid
and t_sells.f_pid=t_part.f_pid) as subtable
结果集:
avgPrice
25
(1 rows)
说明:我们要查询出供应商中的最高的平均零件价格,首先我们会想到 MAX(AVG(F_PRICE)),但我们可以这么写(请参考3.1.6.2)。那么我们首先利用子查询出每个供应商的零件平均价格,然后对子查询进行聚集统计出其中平均价格最高者。
3.1.7Union, Intersect, Except
这一组操作符分别计算两个子查询产生的元组的联合,相交和相异。
UNION语句格式:
Union(«Set1», «Set2»[, ALL])
INTERSECT语句格式:
Intersect («Set1», «Set2»[, ALL])
EXCEPT语句格式:
Except («Set1», «Set2»[, ALL])
注:可选ALL保留重复项。
下面我们仅以Union来举例,其他操作符与其类似。
要求:查询名为Jones或Adams的供应商信息
语句:select * from t_supplier
where f_sname='Jones'
union
select * from t_supplier
where f_sname='Adams'
结果集:
f_sid | f_sname | f_city
2 Jones
Paris
3 Adams
Rome
注:当然我们完全可以不使用UNION而得到我们需要的查询结果,这个自立仅仅是为了让我们体会一下UNION的用法。
3.2数据更新语句
数据更新包括对数据插入、删除、修改操作。
3.2.1数据插入
语句格式:
INSERT INTO 基本表名[(列名表)] values (元组值)
或
INSERT INTO 基本表名(列名表) SELECT 查询语句
注:第二种插入方式可将一个查询的结果集插入指定表中,要求查询结果集字段的名称、类型、顺序必须与指定表的列对应一致;这种数据插入方式在实际应用中非常有效,大家体会一下。
3.2.2数据删除
语句格式:
DELETE FROM 基本表名 [ WHERE 条件表达式]
3.2.3数据修改
语句格式:
UPDATE 基本表名 SET 列名=值表达式,[列名=值表达式...] [ WHERE 条件表达式]
3.2.4对视图的更新
我们知道,对视图的查询是和基本表相同的,但是更新操作则受到下列三条规则的限制:
· 如果视图是从多个基本表使用联接操作导出的,则不允许更新。
· 如果导出的视图使用了分组和聚合操作,也不允许更新。
· 如果视图是从单个基本表使用选择和投影操作导出的,并且包括了基本表的主键或某个候选键,则可以执行操作。(这就相当于在基本表上操作)。
4.数据控制语言(DCL)
4.1权限控制
用户权限是指用户对表、视图、存储过程可以执行哪些操作(如INSERT、DELETE、UPDATE、EXECUTE),数据控制语言(DCL,Data Control Language)即是用来对这种用户权限进行管理。
4.1.1授予用户访问权限
语句格式:
GRANT {ALL|STATEMENT[SELETE,INSERT,UPDATE,DELETE]}
{[ON{tableview} [(column[,…,n])]]…} TO accout
4.1.2拒绝用户访问权限
语句格式:
REVOKE {ALL|STATEMENT[SELETE,INSERT,UPDATE,DELETE]}
{[ON{tableview} [(column[,…,n])]]…} TO accout
4.1.3解除用户访问权限
语句格式:
DENY {ALL|STATEMENT[SELETE,INSERT,UPDATE,DELETE]}
{[ON{tableview} [(column[,…,n])]]…} TO accout
4.2事务控制
事务是一种机制,是一个操作序列,它包含了一组数据库操作命令,所有的命令作为一个整体一起向系统提交或撤销操作请求,即要么都执行,要么都不执行。因此,事务是一个不可分割的工作逻辑单元,类似于操作系统中的原语。在数据库系统上执行并发操作时,事务是作为最小的控制单元来使用的。
4.2.1事务开始
语句格式:
BEGIN TRAN[SACTION] [transaction_name|@tran_name_variable]
4.2.2事务结束
语句格式:
COMMIT TRAN[SACTION] [transaction_name|@tran_name_variable]
注:以前两个命令之间的语句被视为一体,只有当执行到COMMIT TRANSACTION时,事务中对数据库的更新操作才算确认。
4.2.3事务回滚
事务回滚是指当事务中的一条语句执行出错时,将对数据库的操作恢复到事务执行前的状态或某个位置。
语句格式:
ROLLBACK TRAN[SACTION]
[transaction_name|@tran_name_variable|savepoint_name|@savepoint_variable]
5. 流程控制语言
就像其他语言一样,SQL语言也可以进行流程的控制,在存储过程、触发器等的编程过程中,我们会有更深刻的体会。这里我们仅给出流程控制语言中的关键字和描述,大家在以后的数据库编程中还会逐渐了解这一点。
关键字
描述
BEGIN...END
定义语句块。
BREAK
退出最内层的 WHILE 循环。
CONTINUE
重新开始 WHILE 循环。
GOTO label
从 label 所定义的 label 之后的语句处继续进行处理。
IF...ELSE
定义条件以及当一个条件为 FALSE 时的操作。
RETURN
无条件退出。
WAITFOR
为语句的执行设置延迟。
WHILE
当特定条件为 TRUE 时重复语句。