📄 sql server
字号:
作者:转转
日期:2000-12-12 15:07:50
本段文章节选自铁道出版社新出的《用BackOffice建立Intranet/Extranet应用》一书(现已在海淀图书城有售,外地或者需要送货上门的读者可以到www.wanbook.com.cn或www.e-bookshop.com.cn上在线购买。本书书号为ISBN7113039448)。本书详尽地讲述了如何使用微软BackOffice系列产品来组建Intranet/Extranet应用。通过它您将掌握NT的安装和设置、使用IIS建立Web站点、通过ILS建立网络会议系统、用Exchange建立企业的邮件和协作系统、用SQL Server建立Web数据库应用、用Proxy Server建立同Internet安全可靠的连接、用Media Server建立网络电视台/广播站、用Chart server建立功能强大的聊天室、用Site Server建立个性化的邮件列表和分析网站的访问情况、用Commerce Server建立B2B或B2C的电子商务网站。此外本书还对网络的安全性进行了讨论,从而指导您建立一个更为健壮和安全的网络应用。阅读本书之后,您将发现实现丰富多彩的网络应用原来这样简单……
绝对原创,欢迎转载。但请务必保留以上文字。
技巧:游标的定义和使用
一个游标的定义及使用的过程如下:
1:定义游标,为其指定一个查询语句并对游标的各种属性和选项进行设置。
2:打开游标,通过OPEN语句可以打开并填充一个已经定义的游标。
3:将游标所对应记录中的数据取出或对其进行修改。通常读取游标数据的方法是将它赋给一些变量。
4:关闭游标,通过CLOSE语句来实现游标的关闭。一个已经关闭的游标,可以再次通过OPEN语句将其打开。
5:释放游标,对于游标的释放,使用deallocate语句。一个游标一旦被释放,其占用的资源也将被释放。如果想要再次使用它,只能对其进行重新定义。
游标的定义:
既然游标是用于对结果集合中的记录进行操作,那么对其的定义就必然会包含一个返回结果集合的查询。定义游标使用DECLARE CURSOR语句,它具有两种语法结构。一种为兼容SQL-92而保留的,一种为SQL Server自己的"方言"(Transact-SQL)。其语法结构分别如下:
SQL-92语法结构:
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
其中cursor_name为定义游标的名字。
INSENSITIVE选项指明查询的结果集将保存在tempdb之中。也就是说为结果集建立了一个份临时拷贝。所有的游标操作都是基于此临时拷贝的。如果在此之后原来表中的数据发生了变化,也不会反映到此游标的结果集之中了。
SCROLL选项则指明游标可以使用哪些提取记录的方式,其可以有如下选择:
■ FIRST:提取游标的结果集中的第一个记录。
■ LAST:提取游标的结果集中的最后一个记录。
■ PRIOR:提取游标的结果集中当前记录的前一个记录。
■ NEXT:提取游标的结果集中当前记录的后一个记录。
■ RELATIVE n:提取游标的结果集中当前记录之后(n为正数)或之前(n为负数)的第n个记录。
■ ABSOLUTE n:提取游标的结果集中的第n个记录。
如果不指明SCROLL选项,在默认情况下只支持NEXT方式。
select_statement为产生结果集的SQL查询语句,但其中不能包含COMPUTE、COMPUTE BY、FOR BROWSE、INTO这些关键字。
READ ONLY选项指明所定义的游标为只读游标,它禁止通过游标来修改表中的数据。
UPDATE [OF column_name [,...n]]选项指明可以通过游标来修改表中的数据。并可以通过OF column_name [,...n]参数来限定只能对表中的哪些字段进行修改。
Transact-SQL语法结构:
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,...n]]]
其中cursor_name、SCROLL、FOR select_statement、FOR UPDATE [OF column_name [,...n]]、READ_ONLY等参数和选项的含义同SQL-92。
LOCAL和GLOBAL选项指明所定义的游标为局部游标还是全局游标。局部游标作用范围为定义它的批命令、存贮过程或触发器。而全局游标的作用范围为当前的链接。如果不指明此选项,则由数据库的default to local cursor选项(此选项默认为FALSE)来决定。所以默认情况下,定义的都是GLOBAL型的游标。可以通过系统存贮过程sp_dboption来修改数据库的default to local cursor选项。
FORWARD_ONLY选项指明只能以NEXT的方式提取游标结果集中的记录。
STATIC的含义和SQL-92中的INSENSITIVE选项相同。
KEYSET指明建立的游标的结果集中记录的顺序是固定的。所有能够唯一标识结果集中记录的关键字都将存贮到tempdb中的一个临时表中(键集)。
DYNAMIC指明定义的游标为动态游标。任何影响结果数据集的修改都将被反映出来。也就是说,游标的结果集中的数据同数据库中的数据会同步地改变。而对于动态游标,不能使用ABSOLUTE方式来提取结果集中的记录。
FAST_FORWARD指明定义的游标为FORWARD_ONLY且只读。在指定了SCROLL和 FOR UPDATE选项后,不能指定此选项。而且它同FORWARD_ONLY选项互斥。
SCROLL_LOCKS指明在提取游标结果集中的记录时,将其对应的表中的记录进行锁定。从而阻止其他用户对此记录的修改。
OPTIMISTIC指明在提取游标结果集中的记录时,不将其对应表中的记录进行锁定。如果通过游标对记录进行修改,则系统先检测记录是否发生的改变;如果改变,则取消记录的修改操作。
TYPE_WARNING指明系统在使用的SQL语句与游标指定的类型不符时,进行隐含游标类型转换时是否发送警告信息。
我们在上面的代码中使用的是SQL-92的语法结构。
此外,还可以先简单地定义一游标变量,然后再通过SET语句对此游标进行具体的定义。比如可以通过下面的语句来完成我们在上面的游标定义(此语句定义的将是一个游标变量):
declare @point cursor
set @point=cursor
for
select distinct banmian
from gaojian
where kanwu='出版报' and datepart(yy,riqi)=datepart(yy,getdate())
and datepart(dy,riqi)=datepart(dy,getdate())
for read only
此游标的结果集为当日报纸的所有版面的名称。
游标的打开:
在使用游标之前,需要先将其打开(对游标进行数据填充)。通过OPEN语句来打开游标,其语法结构如下:
OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}
其中cursor_name和cursor_variable_name参数为游标或游标变量的名字,而GLOBAL选项用于指明打开的是一个全局游标。如果存在同名的局部游标和全局游标,则使用GLOBAL选项打开全局游标;而不使用GLOBAL选项时,将打开局部游标。
在打开游标之后,可以通过全局变量@@CURSOR_ROWS来读取游标结果集中的记录数目。@@CURSOR_ROWS变量的值可以为下面几种:
-m:说明游标为异步方式填充,m的值为当前键集中的记录数目。
-1:游标为动态的,其结果集是不断变化的,所以无法确定。
0:游标未打开或已经被释放。
n:游标已被完全填充,n为游标的结果集中记录的数目。
对于@@CURSOR_ROWS变量的取值,请见下面的例子:
declare point cursor
for
select distinct banmian
from gaojian
where kanwu='出版报' and datepart(yy,riqi)=datepart(yy,getdate())
and datepart(dy,riqi)=datepart(dy,getdate())
for read only
open point
select @@CURSOR_ROWS
close point
select @@CURSOR_ROWS
DEALLOCATE point
select @@CURSOR_ROWS
其运行结果如下:
-----------
9
(1 row(s) affected)
-----------
0
(1 row(s) affected)
-----------
0
(1 row(s) affected)
提取游标结果集中记录的数据:
通过FETCH语句来提取游标结果集中记录,其语法结构如下:
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE {n | @nvar}
| RELATIVE {n | @nvar}
]
FROM
]
{ { [GLOBAL] cursor_name } | @cursor_variable_name}
[INTO @variable_name[,...n] ]
其中cursor_name和cursor_variable_name参数为游标或游标变量的名字。GLOBAL选项指明所操作的是一个全局游标。而NEXT、PRIOR、FIRST、LAST、ABSOLUTE和RELATIVE分别为提取记录的方式。其含义我们在前面定义游标的SCROLL选项时已经讲述了。如果不指明操作的方式,系统将默认使用NEXT方式。
INTO子句用于将提取的数据保存到局部变量之中。变量的数目应该和游标结果集中的字段数目相同。且其数据类型也应该一一对应。
在执行FETCH语句之后,可以通过全局变量@@FETCH_STATUS来得到执行状态。@@FETCH_STATUS变量可以有下列的取值:
0:说明FETCH语句执行成功。
-1:说明要提取的记录已经超出结果集的范围。比如在当前记录已经为结果集中最后一条记录时,再次使用NEXT方式来运行FETCH语句。
-2:说明要提取的记录在结果集中已经不存在。
游标的关闭:
关闭游标使用CLOSE语句,其语法结构如下:
CLOSE { { [GLOBAL] cursor_name } | cursor_variable_name }
其中各参数的含义同OPEN语句。
游标的释放:
释放游标使用DEALLOCATE语句,其语法结构如下:
DEALLOCATE { { [GLOBAL] cursor_name } | @cursor_variable_name}
其中各参数的含义同OPEN语句。
在上面的代码中,我们还使用了BEGIN…END和WHILE等流控制语句。其含义同我们在一些其他编程语言中使用的流控制关键字相类似。本书将在稍后的内容中详细介绍它们。
各个版面的文章列表页面文件的输出使用list2.tml,其代码如下:
<html>
<title>今日本版文章</title>
<body background="images/WB00703_.gif">
<TABLE BORDER="BORDER" ALIGN="CENTER">
<TR>
<TD>题目</TD>
<TD>稿件来源</TD>
</TR>
<%begindetail%>
<TR>
<TD><a href="<%insert_data_here%>.htm"><%insert_data_here%></TD>
<TD><%insert_data_here%></TD>
</TR>
<%enddetail%>
</TABLE>
</body>
</html>
输出的结果页面文件同我们在前面用IDC技术得到的页面相类似。而代码中的@lists变量用于产生这些页面文件的文件名。每当游标移向下一个记录时,@lists就会加一。从而我们得到了名字为1.htm~n.htm(n为当日版面的总数)的一系列页面文件。在每个文件中,都包含相应版面的文章列表。
下面的代码将为当日报纸的每篇文章产生一个页面文件。
declare @gaojianid int
declare point2 cursor for
select gaojian.id
from gaojian
where kanwu='出版报' and datepart(yy,riqi)=datepart(yy,getdate()) and
datepart(dy,riqi)=datepart(dy,getdate())
for read only
open point2
fetch point2 into
@gaojianid
while (@@fetch_status=0)
begin
set @filename=@filepath+convert(varchar(64),@gaojianid)+'.htm'
set @search='SELECT timu,laiyuan,neirong,left(pics,10)+ STUFF(pics,1,21,''''),yuanwen
FROM gaojian
WHERE id='+convert(varchar(64),@gaojianid)
execute sp_makewebtask
@outputfile=@filename,
@query=@search,
@templatefile='d:\test\outfile.tml',
@codepage=936
fetch point2 into
@gaojianid
end
close point2
deallocate point2
产生的页面文件将使用文章的id字段作为文件名的前部。而代码中用下划线标出的部分使用left和stuff两个字符串函数对文章中附图的超链接进行了修改,使其能够在静态页面中正常显示。
此段代码使用的输出模板文件为outfile.tml,其代码如下:
<html>
<title>文章信息</title>
<body background="images/WB00703_.gif">
<%begindetail%>
<h3>题目:<%insert_data_here%></h3>
<hr>
<h3>来源:<%insert_data_here%></h3>
<p>
<B><font SIZE="3">内容:<%insert_data_here%></font></B>
<hr>
<script>
var pic='<%insert_data_here%>>';
var pic2=pic.charAt(10);
if (pic2!='_'){
document.write('<h3>附图:<p>'+pic+'</h3>');
}
</script>
<hr><B><font SIZE="3">原文:<%insert_data_here%></font></B>
<%enddetail%>
</TABLE>
</body>
</html>
其中的Java语句用于对图像的超链接进行判断。如果其没有指向某个图像文件,则不将其显示出来。以免在页面上出现一个错误的图像链接标志。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -