数据库的视图和游标

🎆视图
视图一经定义以后,就可以象表一样被查询、修改、删除和更新。使用视图有下列优点:
🎯1.创建视图
1.在对象资源管理器中创建视图
下面以在xsbook数据库中创建cs_xs(描述计算机专业学生情况)视图说明在创建视图的过程。
2.使用CREATE VIEW语句创建视图
T-SQL中用于创建视图的语句是CREATE VIEW语句,例如用该语句创建视图cs_xs,其表示形式为:
CREATE VIEW cs_xs
AS
SELECT *
FROM xs
WHERE 专业 = '计算机'
注意:CREATE VIEW必须是批命令的第一条语句。
CREATE VIEW的语法格式为:
CREATE VIEW [ <数据库架构名>. ] <视图名> [ (<列名> [ ,...n ] ) ]
AS select_statement
[ WITH CHECK OPTION ]
说明:
【例】 创建cs_jy视图,包括计算机专业各学生的借书证号、其借阅图书的索书号及借书时间。要保证对该视图的修改都要符合专业为计算机这个条件。
CREATE VIEW cs_jy
AS
SELECT xs.借书证号, 索书号, 借书时间
FROM xs, jy
WHERE xs.借书证号 = jy.借书证号 AND 专业 = '计算机'
WITH CHECK OPTION
视图cs_jy的属性列包括了xs表的借书证号、jy表的索书号和借书时间。
【例】 创建计算机专业学生在2022年4月20日以前的借书情况视图cs_jy_430。
CREATE VIEW cs_jy_430
AS
SELECT 借书证号, 索书号, 借书时间
FROM cs_jy
WHERE 借书时间<'20220420'
这里的视图cs_jy_430就是建立在视图cs_jy之上的。
【例】 定义一个反映图书借出量的视图。
CREATE VIEW LENDNUM(ISBN,num)
AS
SELECT ISBN,复本量-库存量
FROM book
说明:LENDNUM视图是一个带表达式的视图,其中的借出量num是通过计算得到的。
【例】 定义学生所借图书总价值的视图。
CREATE VIEW TOTPRICE(借书证号,PRICE)
AS
SELECT jy.借书证号,SUM(价格)
FROM xs,jy,book
WHERE xs.借书证号=jy. 借书证号 AND jy.ISBN=book.ISBN
GROUP BY jy.借书证号
🎯2.查询视图
【例】 查找计算机专业在1996年1月1日以后出生的学生情况。
本例对cs_xs视图进行查询:
SELECT *
FROM cs_xs
WHERE 出生时间>'19960101'
【例】 查找在2022年3月11日借了书的学生的借书证号和索书号。
本例对cs_jy视图进行查询:
SELECT 借书证号, 索书号
FROM cs_jy
WHERE 借书时间='20220311'
【例】 查找在2022年4月30日以前借了书的学生的借书证号和索书号。
本例对cs_jy_430视图进行查询:
SELECT 借书证号, 索书号
FROM cs_jy_430
【例】 查找被借出数在3本或3本以上的图书的ISBN和借出数。
本例对LENDNUM视图进行查询:
SELECT *
FROM LENDNUM
WHERE num>=3
【例】 查找所借图书价值在100元以上的学生的借书证号和所借图书价值。
本例对TOTPRICE视图进行查询:
SELECT *
FROM TOTPRICE
WHERE PRICE>100
使用视图查询时,若其关联的基本表中添加了新字段,则必须重新创建视图才能查询到新字段。例如,若xs表新增了“籍贯”字段,那么在其上创建的视图cs_xs若不重建视图,那么以下查询:
SELECT * FROM cs_xs
结果将不包含“籍贯”字段。只有重建cs_xs视图后再对它进行查询,结果才会包含“籍贯”字段。
🎯3.更新视图
要通过视图更新基本表数据,必须保证视图是可更新视图。一个可更新视图可以是以下情形之一:
例如,前面创建的视图cs_xs、cs_jy、cs_jy_430是可更新视图,而LENDNUM、TOTPRICE是不可更新的视图。
1.插入数据
使用INSERT语句通过视图向基本表插入数据。
【例】 向计算机专业学生视图cs_xs中插入一个新的学生记录,借书证号为131180,姓名为坤坤,性别为男,出生时间为1996-04-29。
INSERT INTO cs_xs(借书证号,姓名,性别,出生时间, 专业,借书量)
VALUES('131180','坤坤', 0,'1996-4-29', '计算机',0)
使用SELECT语句查询cs_xs依据的基本表xs:
SELECT * FROM xs
将会看到该表已添加了(‘131180’, ‘坤坤’, 0,‘1996-4-29’, ‘计算机’,0,NULL)行。
2.修改数据
【例】 将计算机专业学生视图cs_xs中借书证号为“131180”的学生姓名改为“李军”。
UPDATE cs_xs
SET 姓名='李军'
WHERE 借书证号='131180'
3.删除数据
使用DELETE语句可以通过视图删除基本表的数据。但要注意,对于依赖于多个基本表的视图(不包括分区视图),不能使用DELETE语句。例如,不能通过对cs_jy视图执行DELETE语句而删除与之相关的基本表xs及jy表的数据。
【例】 删除计算机专业学生视图cs_xs中借书证号为131180的记录。
DELETE FROM cs_xs
WHERE 借书证号='131180'
🎯4.修改视图的定义
1.通过对象资源管理器修改视图
启动“SQL Server Management Studio,在“对象资源管理器”中展开“数据库”→“xsbook”→“视图”→选择“dbo.cs_xs”,右击鼠标,在弹出的快捷菜单中选择“设计”菜单项,进入视图修改窗口。在该窗口与创建视图的窗口类似,其中可以查看并可修改视图结构,修改完后单击保存图标按钮即可。
2.使用ALTER VIEW语句修改视图
ALTER VIEW语句的语法格式为:
ALTER VIEW [ <数据库架构名>. ] <视图名> [ ( <列名> [ ,...n ] ) ]
AS select_statement
[ WITH CHECK OPTION ]
【例】 将cs_xs视图修改为只包含计算机专业学生的借书证号、姓名和借书量。
ALTER VIEW cs_xs
AS
SELECT 借书证号, 姓名, 借书量
FROM xs
WHERE 专业 = ‘计算机’
【例】 修改视图cs_jy中包含的列名:借书证号、姓名、索书号、和借书时间
ALTER VIEW cs_jy
AS
SELECT xs.借书证号, xs.姓名, 索书号, 借书时间
FROM xs,jy
WHERE xs.借书证号 = jy.借书证号 AND 专业 = '计算机'
WITH CHECK OPTION
🎯5.删除视图
1.通过对象资源管理器删除视图
在“对象资源管理器”中删除视图的操作方法是:
在“视图”目录下选择需要删除的视图,右击鼠标,在弹出的快捷菜单上选择“删除”菜单项,出现删除对话框,单击“确定”按钮,即删除了指定的视图。
2.使用DROP VIEW语句删除视图
语法格式:
DROP VIEW [<数据库架构名>. ] <视图名> [ ...,n ] [ ; ]
使用DROP VIEW可删除一个或多个视图。例如:
DROP VIEW cs_xs, cs_jy
将删除视图cs_xs和cs_jy。
🎆游标
🎯1.游标概念
一个对表进行操作的T-SQL语句通常都可产生或处理一组记录,但是许多应用程序,尤其是T-SQL嵌入到的主语言(如C、VB、PowerBuilder或其它开发工具)通常不能把整个结果集作为一个单元来处理,这些应用程序就需要一种机制来保证每次处理结果集中的一行或几行,游标(cursor)就提供了这种机制。
SQL Server通过游标提供了对一个结果集进行逐行处理的能力,游标可看作一种特殊的指针,它与某个查询结果相联系,可以指向结果集的任意位置,以便对指定位置的数据进行处理。使用游标可以在查询数据的同时对数据进行处理。
🎯2.声明游标
1.SQL标准语法
在SQL标准中,声明游标的语句格式为:
DECLARE <游标名> [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF <列名> [ ,…n ] ] } ]
以下是一个符合SQL标准的游标声明:
DECLARE xs_CUR1 CURSOR
FOR
SELECT 借书证号,姓名,性别,出生时间,借书量
FROM xs
WHERE 专业 = '计算机'
FOR READ ONLY
该语句定义的游标与单个表的查询结果集相关联,是只读的,游标只能从头到尾顺序提取数据,相当于下面所讲的只进游标。
2.T-SQL扩展
T-SQL扩展的游标声明语句格式为:
DECLARE <游标名> CURSOR
[ LOCAL | GLOBAL ] /*游标作用域*/
[ FORWORD_ONLY | SCROLL ] /*游标移动方向*/
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] /*游标类型*/
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] /*访问属性*/
[ TYPE_WARNING ] /*类型转换警告信息*/
FOR select_statement /*SELECT查询语句*/
[ FOR UPDATE [ OF <列名> [ ,…n ] ] ] /*可修改的列*/
以下是一个T-SQL扩展游标声明:
DECLARE xs_CUR2 CURSOR
DYNAMIC
FOR
SELECT 借书证号,姓名,借书量
FROM xs
WHERE 专业 = '计算机'
FOR UPDATE OF 姓名
该语句声明一个名为xs_CUR2的动态游标,可前后滚动,可对姓名列进行修改。
🎯3.打开游标
声明游标后,要使用游标从中提取数据,就必须先打开游标。在T-SQL中,使用OPEN语句打开游标,其格式为:
OPEN { { [ GLOBAL ] <游标名> } | <游标变量名> }
GLOBAL说明打开的是全局游标,否则打开局部游标。
OPEN语句打开游标,然后通过执行在DECLARE CURSOR(或 SET cursor_variable)语句中指定的T-SQL语句填充游标(即生成与游标相关联的结果集)。
例如,语句:
OPEN xs_CUR1
打开游标xs_CUR1。该游标被打开后,就可以提取其中的数据。
【例】 定义游标xs_CUR3,然后打开该游标,输出其行数。
DECLARE xs_CUR3 CURSOR
LOCAL SCROLL SCROLL_LOCKS
FOR
SELECT 借书证号,姓名,借书量
FROM xs
FOR UPDATE OF 姓名
OPEN xs_CUR3
SELECT '游标xs_CUR3数据行数' = @@CURSOR_ROWS
语句的执行结果如图4.38所示。
🎯4.读取数据
游标打开后,就可以使用FETCH语句从中读取数据。FETCH语句的格式为:
FETCH[ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar} ]
FROM ]
{ { [ GLOBAL ] cursor_name } | @cursor_variable_name }
[ INTO @variable_name [ ,…n ] ]
【例】 从游标xs_CUR1中提取数据。
OPEN xs_CUR1
FETCH NEXT FROM xs_CUR1
语句的执行结果如图所示。
【例】从游标xs_CUR2中提取数据。
OPEN xs_CUR2
FETCH FIRST FROM xs_CUR2
- 读取游标第一行(当前行为第一行),结果如图所示。
FETCH NEXT FROM xs_CUR2
- 读取下一行(当前行为第二行),结果如图所示:
FETCH PRIOR FROM xs_CUR2
- 读取上一行(当前行为第一行),结果如图所示。
FETCH LAST FROM xs_CUR2
- 读取最后一行(当前行为最后一行)。
FETCH RELATIVE -2 FROM xs_CUR2
- 读取当前行的上二行(当前行为倒数第一行)。
FETCH语句的执行状态保存在全局变量@@FETCH_STATUS中,其值为0表示上一个FETCH执行成功;为-1表示所要读取的行不在结果集中;为-2表示被提取的行已不存在(已被删除)。
例如继续执行如下语句:
FETCH RELATIVE 3 FROM xs_CUR2
SELECT 'FETCH执行情况' = @@FETCH_STATUS
执行结果为-1。
🎯5.关闭游标
游标使用完以后,要及时关闭。关闭游标使用CLOSE语句,格式为:
CLOSE { { [ GLOBAL ] <游标名> } | @<游标变量名> }
例如:
CLOSE xs_CUR2
将关闭游标xs_CUR2。
🎯6.删除游标
游标关闭后,其定义仍在,需要时可用OPEN语句打开它再使用。若确认游标不再需要,就要释放其定义占用的系统空间,即删除游标。删除游标使用DEALLOCATE语句,格式为:
DEALLOCATE { { [ GLOBAL ] <游标名> } | @<游标变量名>e }
例如:
DEALLOCATE xs_CUR2
将删除游标xs_CUR2。