标题SQL Server静态页面导出技术
日期:    作者:   来源:
文章打印自:
访问文章完全地址:
头部广告
SQL Server静态页面导出技术
本段文章节选自铁道出版社新出的《用BackOffice建立Intranet/Extranet应用》一书(现已在海淀图书城有售)。本书详尽地讲述了如何使用微软BackOffice系列产品来组建Intranet/Extranet应用。通过它您将掌握NT的安装和设置、使用IIS建立Web站点、通过ILS建立网络会议系统、用Exchange建立企业的邮件和协作系统、用SQL Server建立Web数据库应用、用Proxy Server建立同Internet安全可靠的连接、用Media Server建立网络电视台/广播站、用Chart server建立功能强大的聊天室、用Site Server建立个性化的邮件列表和分析网站的访问情况、用Commerce Server建立B2B或B2C的电子商务网站。此外本书还对网络的安全性进行了讨论,从而指导您建立一个更为健壮和安全的网络应用。阅读本书之后,您将发现实现丰富多彩的网络应用原来这样简单……
绝对原创,欢迎转载。但请务必保留以上文字。



我们在前面对静态页面导出技术进行了初步的介绍,现在我们通过一些实例来完成对它的详细讲解。
静态页面导出可以通过调用存贮过程和使用Enterprise Manager中的向导两种方式来完成。通过向导的方式可以很容易地将数据库的数据导出为静态页面或建立导出任务。使用起来十分方便,但是其的灵活性不如通过调用存贮过程的方法来得好。下面我们首先介绍如何通过向导建立一个静态页面导出。
6.9.4.1. 使用Enterprise Manager进行静态页面导出
假设我们将建立一个静态页面,其内容为每日报纸上刊载的所有文章的题目及其所在版面。而此页面的内容要求每当数据库中的数据发生变化时都能随之发生变化。下面我们来看看其具体的实现过程:
在Enterprise Manager中找到要进行静态页面导出的服务器,打开其Management容器,右击Web Publishing对象。从弹出的快捷菜单中选择New Web Assistant Job选项。将启动静态页面导出的向导(如下图)。

图6.9.4.1-1静态页面导出向导步骤1,提示信息
可以看到,此向导分为三步:定义导出数据、调度导出任务、格式化Web页面。点击下一步继续。
随后将要我们选择要导出的数据来自哪一个数据库,我们选择test后,点击下一步继续(如下图)。

图6.9.4.1-2静态页面导出向导步骤2,选择导出数据库
随后将要求我们输入此导出任务的名称(默认为test Web Page),并选择导出数据的方式(如下图)。

图6.9.4.1-3静态页面导出向导步骤3,选择导出方式
其中有以下三种方式可供选择:
■ Data from the tables an columns that Iselect:直接从表中选择要导出的字段。
■ Result set(s) of a stored procedure Iselect:导出的数据来自一个存贮过程的运行结果。
■ Data from the Transact-SQL statement Ispecify:导出的数据来自一段SQL语句。
根据我们的应用要求,选择第三项之后,点击下一步继续。
随后根据我们选择的导出方式,将要求输入一段SQL语句(如下图)。

图6.9.4.1-4静态页面导出向导步骤4,输入导出查询语句
我们输入如下的一段SQL语句:
select id as '编号',banmian as '版面',timu as '题目'
from gaojian
where kanwu='出版报' and datepart(yy,riqi)=datepart(yy,getdate()) and
datepart(dy,riqi)=datepart(dy,getdate())
输入完成后,点击下一步继续。
随后将要我们对此任务的调度方式进行选择(如下图)。

图6.9.4.1-5静态页面导出向导步骤5,设置导出任务
其中有下面几个选项可供选择:
■ Only one time when Icomplete this wizard:在完成此向导过程时执行,并且只执行这一次。
■ On demand:在需要的时候执行。
■ Only one time at:只在指定的时刻执行一次。
■ When the SQL Server data changes:当数据库中的数据发生改变时执行。
■ At regularly scheduled intervals:周期性的执行此任务。
对话框的下部有一个Generate a Web page when the wizard is completed选择框,用来指明是否在此向导过程完成时执行一次页面导出(默认选择此项)。
根据我们的需要,应该选择When the SQL Server data changes一项。点击下一步继续。
接下来的一步根据上一步的选择而会有所不同。我们看到的将是如下图所示的对话框:

图6.9.4.1-6静态页面导出向导步骤6,指定跟踪字段
向导将要求我们选择对哪个表中的哪些字段进行跟踪。一旦表中的这些字段发生了改变(在插入、删除记录及修改记录时),将会运行此任务来更新静态页面的内容。我们选择对gaojian表中的id、riqi、laiyuan和timu四个字段进行跟踪。选择完成后,点击下一步继续。
随后将要我们选择静态页面的存放位置及文件名(如下图)。我们可以将其放在IIS中某一虚拟目录所在的目录下。从而可以让用户通过网页对其进行访问。

图6.9.4.1-7静态页面导出向导步骤7,指定静态文件存放位置
输入合适的存放目录和文件名之后,点击下一步继续。
随后将要对导出页面的格式和编码进行设定(如下图)。

图6.9.4.1-8静态页面导出向导步骤8,指定静态文件的格式和编码
对于页面格式,我们可以让系统自动完成其格式的设定,也可以通过指定一个模板文件来对其进行格式化。后面的内容将对模板文件进行讨论。这里我们现选择由系统自动完成页面的格式化工作。在Use character set下拉列表框中可以对页面的字符集进行选择,由于我们使用中文,所以应该选择简体中文(GB2312)。点击下一步继续。
接下来将要输入页面标题和SQL语句执行结果表的标题并为其选择字体的大小(如下图)。

图6.9.4.1-9静态页面导出向导步骤9,指定静态页面标题
对话框下部的Apply a time and data stamp to the Web page选择框用来决定是否在页面中显示页面生成的日期和时间,从而使用户得知此页面中的数据为何时生成的。设置完成后,点击下一步继续。
随后将对SQL语句执行的结果表进行设置(如下图)。

图6.9.4.1-10静态页面导出向导步骤10,静态页面显示效果设置
其中Yes,display column names和No,display data only单选框用来指明结果表中是否包含字段名(在表头中显示)。根据我们的需要,选择Yes,display column names单选框,显示字段名。而其下的一些选项用于对表中的一些字体效果进行设置。可以选择固定宽度字体(Fixed)、比例宽度字体(Proportional)、加黑(Bold)和斜体(Italic)四种。而Draw border Lines around the HTML table选择框用于指明是否为结果表画出表框。设置完成后,点击下一步继续。
随后将提示是否在页面中加入超链接(如下图)。

图6.9.4.1-11静态页面导出向导步骤11,设置页面超链接
可以有以下三种选择:
■ No:不在页面中加入超链接。我们选择此项。
■ Yes,add one hyperlink:加入一条超链接。并为其指明连接和显示信息。
■ yes,add a list of hyperlink URLs:加入一个超链接列表。此列表是通过一段SQL语句从数据库的某个表中得到的。
选择第一个选项后,点击下一步继续。
接下来我们可以对返回的全部记录的数量和每页返回的结果数量进行限制(如下图)。

图6.9.4.1-12静态页面导出向导步骤12,返回结果数量限制
我们可以选择"No,return all rows of data"单选框,不对返回的总记录数目进行限制;也可以选择"Yes,Return the first rows of data"单选框来对返回的记录数目进行限制(通过在其后的文本输入框中输入要返回的最多记录数)。
选择了"No,put all data in one svrolling page"单选框则意味着所有返回的记录都将被放在一个页面文件之中。而如果选择了"Yes,link the successive pages together"单选框则可以将返回的记录放在许多页面文件中,从而减小结果页面的长度。方便用户对其进行浏览。可以在其后的文本输入框中输入输入每个页面文件所包含最多的记录数目。我们选择每个页面最多可包含20个记录。设定完成后,点击下一步继续。
随后向导将提示我们已经完成了静态页面导出任务的设置,并显示它的一些相关信息(如下图)。

图6.9.4.1-13静态页面导出向导步骤13,完成确认信息
如果点击Write Transact-SQL to file按钮,则可将此任务以一个SQL语言脚本文件的方式保存下来。这样可以在以后通过运行这个脚本来再次建立这个任务。或者对脚本的内容进行修改,对其实现的功能作出一些调整。根据我们的设置,其产生的SQL语句如下:
EXECUTE sp_makewebtask @outputfile = N'D:\test\cbb\ttt.htm',
@query=N'select id,banmian,timu
from gaojian where kanwu=''出版报'' and
datepart(yy,riqi)=datepart(yy,getdate())
and datepart(dy,riqi)=datepart(dy,getdate())
order by banmian ',
@fixedfont=1,
@colheaders=0,
@HTMLheader=3,
@webpagetitle=N'Microsoft SQL Server Web Assistant',
@resultstitle=N'Query Results',
@dbname=N'test',
@whentype=10,
@nrowsperpage=20,
@datachg=N'TABLE=gaojian COLUMN=id,timu,laiyuan,riqi',
@procname=N'test Web Page',
@codepage=936,
@charset=N'gb2312'
一旦通过向导完成了静态页面导出任务的设定,就不能再通过Enterprise Manager对其属性进行修改。只能使用SQL语句来修改其各项设置。我们将在后面对sp_makewebtask进行讲解时再对其中各个参数的含义进行分析。
点击完成按钮,结束此任务的设置工作。其产生的一个结果页面如下图所示。

图6.9.4.1-14静态页面导出结果
注意:在设置了这个静态页面导出任务之后,如果你在对稿件进行修改、添加或删除的时候,将会出现一个错误提示。如果你关闭了IE的显示友好的HTTP错误信息功能的话(建议在调试IDC应用时关闭此功能,这样就可以看到由系统返回的详细错误信息)就会看到下面的错误信息:
运行查询错误
[State=42000][Error=229][Microsoft][ODBC SQL Server Driver][SQL Server][Microsoft] [ODBC SQL Server Driver][SQL Server]EXECUTE permission denied on object 'test Web Page', database 'test', owner 'dbo'.
[State=37000][Error=16805][Microsoft][ODBC SQL Server Driver][SQL Server]SQL Web Assistant: Could not execute the SQL statement.
这是由于在省缺情况下,定义的静态页面导出的运行权利并不是默认的赋予每个用户。所以当以editer的身份执行IDC时,就会出现权限没有得到许可的错误信息。不过这并不会影响对稿件数据的操作。
解决这个问题有两种方法,一个是修改相应的对稿件进行插入和修改的IDC文件,将其中的Username和password分别改为sa和sa的口令。这样就会以sa的身份运行此IDC文件,从而就不会再出现错误了。而此方法会造成一些安全上的隐患,如果有人读取了这些IDC文件。他就知道了sa的口令,从而可以以sa的身份登录到数据库之中。对数据库可以进行几乎没有限制的操作和修改。为了避免这种情况的发生,可以通过运行下面的SQL语句来授予editers角色对静态页面导出任务的执行权限:
grant all on test.dbo.[test Web Page] to editers
其中test Web Page为此静态页面导出任务的名字,之所以用中括号将其扩起来的原因是它的名字中包含空格。在SQL Server中,凡是名字中包含空格的对象,在引用其名称时都应该用中括号将其括起来。而且对于这些对象,将不能在Enterprise Manager中对其权限等信息进行修改。而只能通过SQL语句来实现。这是由于Enterprise Manager中的一个bug造成的,在SQL Server的SP3中仍然没有得到休正。
虽然通过Enterprise Manager中的向导来建立静态页面导出任务是一个简单的过程,但是对于一些复杂的情况就显得有些不太适用了。比如,假设我们将要把每天出版报的内容放到Internet上通过静态页面进行发布。这样光依靠Enterprise Manager的向导中提供的功能就远远不够了。只能通过调用sp_makewebtask存贮过程并使用一些技巧来来实现这样比较复杂的任务。
SQL Server静态页面导出技术
本段文章节选自铁道出版社新出的《用BackOffice建立Intranet/Extranet应用》一书(现已在海淀图书城有售)。本书详尽地讲述了如何使用微软BackOffice系列产品来组建Intranet/Extranet应用。通过它您将掌握NT的安装和设置、使用IIS建立Web站点、通过ILS建立网络会议系统、用Exchange建立企业的邮件和协作系统、用SQL Server建立Web数据库应用、用Proxy Server建立同Internet安全可靠的连接、用Media Server建立网络电视台/广播站、用Chart server建立功能强大的聊天室、用Site Server建立个性化的邮件列表和分析网站的访问情况、用Commerce Server建立B2B或B2C的电子商务网站。此外本书还对网络的安全性进行了讨论,从而指导您建立一个更为健壮和安全的网络应用。阅读本书之后,您将发现实现丰富多彩的网络应用原来这样简单……
绝对原创,欢迎转载。但请务必保留以上文字。


使用SQL语句来实现静态页面导出
首先,我们来看看要通过静态页面导出技术实现哪些功能。我们将要把每天报纸的内容按照同IDC应用一样的格式放到出版报在ISP的主页中相应的目录之中(比如99年5月8号的报纸内容就要放到1999-05-08目录之中)。而要想达到这样的效果就需要导出三类文件:每天刊载版面的列表页面文件(每天一个)、每个版面的文章列表页面文件(每天有多少个版面,就有多少个这样的文件)、每篇文章的内容各为一个页面文件(每天有多少文章,就有多少个这样的文件)。
sp_makewebtask存贮过程语法结构和参数含义:
建立静态页面导出任务由sp_makewebtask存贮过程来完成。下面我们来看看其具体的语法结构和参数:
sp_makewebtask [@outputfile =] 'outputfile', [@query =] 'query'
[, ][@fixedfont =] fixedfont]
[, ][@bold =] bold]
[, ][@italic =] italic]
[, ][@colheaders =] colheaders]
[, ][@lastupdated =] lastupdated]
[, ][@HTMLHeader =] HTMLHeader]
[, ][@username =] username]
[, ][@dbname =] dbname]
[, ][@templatefile =] 'templatefile']
[, ][@webpagetitle =] 'webpagetitle']
[, ][@resultstitle =] 'resultstitle']
[
][, [@URL =] 'URL', [@reftext =] 'reftext']
| [, ][@table_urls =] table_urls, [@url_query =] 'url_query']
]
[, ][@whentype =] whentype]
[, ][@targetdate =] targetdate]
[, ][@targettime =] targettime]
[, ][@dayflags =] dayflags]
[, ][@numunits =] numunits]
[, ][@unittype =] unittype]
[, ][@procname =] procname ]
[, ][@maketask =] maketask]
[, ][@rowcnt =] rowcnt]
[, ][@tabborder =] tabborder]
[, ][@singlerow =] singlerow]
[, ][@blobfmt =] blobfmt]
[, ][@nrowsperpage =] n]
[, ][@datachg =] table_column_list]
[, ][@charset =] characterset]
[, ][@codepage =] codepage]

下面对sp_makewebtask存贮过程的参数逐个的进行介绍:
■ outputfile:指明存放导出的静态页面文件的路径和文件名。对于产生多个文件的情况(比如在限制了每个页面的最大记录数目时),系统会自动地在这些文件名的末尾加上数字。
■ query:要由sp_makewebtask存贮过程来执行的SQL语句。其结果数据将用于产生静态页面。同IDC技术相类似,此参数中也允许存在多个查询。
■ fixedfont:指明是否使用固定宽度字体(为1时使用,为0时不使用。默认为1)。
■ bold:是否使用加粗字体。(为1时使用,为0时不使用。默认为0)
■ italic是否使用斜体字体。(为1时使用,为0时不使用。默认为0)
■ colheaders:是否显示字段名(结果数据集合的列标题)。(为1时显示,为0时不显示。默认为1)
■ lastupdated:是否在页面中显示文件的创立时间。(为1时显示,为0时不显示。默认为1)
■ HTMLHeader:页面标题的显示格式。其取值为1~6,对应于HTML语言的H1~H6。
■ Username:指明用来执行SQL语句的用户,默认为连接时的用户(在本应用实例中默认用户为editer)。
■ Dbname:指明在哪个数据库上运行SQL语句。默认为当前数据库。
■ Templatefile:指明模板文件(同IDC技术中的htx文件的作用相类似)的所在路径和文件名。如果使用了模板文件,其他格式控制参数将不再起作用(比如bold、italic和fixedfont等参数)。
■ Webpagetitle:指明页面文件的标题,等效于HTML语句中<TITLE> </TITLE>之间的字符。
■ Resultstitle:用来指定在页面中返回结果数据集之前显示的标题。默认为Query Results。
■ URL:用于指明页面中包含的超链接。必须同reftext参数结合使用。
■ Reftext:URL参数中超链接地址的名称。也就是HTML文件中连接地址的文字部分。如下面的例子中的"文章查询"几个字。
<a HREF="search.idc?" >文章查询</a>
■ table_urls:指明是否使用一个查询来动态的生成页面中的超链接列表(为1时使用,为0时不使用。默认为0)。如果此参数为1时,则不能同时指定URL和reftext参数,且必须同时指定url_query参数。
■ url_query:用来产生超链接列表的查询语句。其返回的第一个字段为链接地址,第二个字段为此地址的名称。
■ whentype:用于指明任务执行的时机。其取值及含义如下:
n 1:系统默认值。指明立即建立任务并执行它建立导出页面。并在执行之后将任务删除。
n 2:建立任务,但并不立即执行它。其执行的日期和时间将分别由targetdate和targettime参数(可选参数)来决定。如果不指明targettime参数,任务将在由targetdate指明的那天的凌晨0点执行。
n 3:每周的n天执行任务,其首次执行时间分别由targetdate和targettime参数(可选参数)来决定。而在此之后则由dayflages参数来指明将会在一周中的哪些天执行此任务。
n 4:每n分钟、小时、天或者周执行一次任务。其首次执行时间分别由targetdate和targettime参数(可选参数)来决定。而时间的间隔分别由numunits和unittype参数来指明。
n 5:由用户来决定何时执行此任务。此任务会被创建但没有进行调度。用户可以通过执行sp_runwebtask来执行此任务。
n 6:指明立即建立任务并执行它建立导出页面。并在执行之后在分别由targetdate和targettime参数(可选参数)指明的日期和时刻执行。
n 7:同3相类似,但它会在任务建立时立即执行一次,所以不需要targetdate参数。
n 8:同4相类似,但它会在任务建立时立即执行一次,所以不需要targetdate参数。
n 9:同5相类似,但它会在任务建立时立即执行一次。
n 10:在任务建立时立即执行一次,以后则在由datachg参数中指定的数据发生变化时执行。
■ targetdate:指明任务执行的日期(如whentype参数为2、3、4、6时),其格式为yyyymmdd。
■ targettime:指明任务执行的时间,其格式为HHMMSS。其默认值为凌晨0点。
■ dayflags:用于指明任务在一周中的哪天执行(如whentype参数为3或7时)。其取值为1、2、4、8、16、32、64分别对应于星期天、星期一、星期二、星期三、星期四、星期五、星期六。如果要指明在每周的多个日子中执行任务,则将它们所代表的值相加即可。比如要想在星期一和星期四执行任务,则此参数等于18(2 16=18)。
■ numunits:同unittype参数一起用于指定任务的执行频度(如whentype参数为4或8时)。其取值范围为1~255。
■ unittype:用于指明numunits参数的时间单位。其取值可以分别为1、2、3、4,对应于小时、天、周和分钟。比如当numunits参数为1,unittype参数为2时,任务将在每两个小时执行一次。
■ procname:指明所建立的任务的名称。
■ maketask:指明是否建立一个任务来执行导出静态页面的存贮过程。其取值可以分别如下:
0:建立一个不加密的存贮过程,但不创建执行该存贮过程的任务。
1:建立一个加密的存贮过程,并创建执行该存贮过程的任务。
2:建立一个不加密的存贮过程,并创建执行该存贮过程的任务(此值为系统默认值)。
■ rowcnt:指明返回SQL语句结果数据集中记录的最大数目。默认为返回所有的记录。
■ tabborder:指明是否在页面中的数据画出表框线。其取值可以为1(画线)或0(不画线),默认值为1。
■ singlerow:指明是否为每个返回的记录都建立一个页面文件。其取值可以为1(建立单独的文件)或0(不为每个记录单独建立文件),默认值为0。
■ blobfmt:指明是否将查询返回的结果集中的ntext和image数据类型的字段独立的放到一个页面文件之中并在主页面文件中加入指向这些文件的超链接。此参数的默认为空。其格式如下:
"%n% FILE=output_filename TPLT=template_filename URL=url_link_name..."
其中n为ntext或image字段在返回结果中的序号。output_filename为ntext和image字段输出文件名;template_filename为其模板文件名;url_link_name为主页面文件中连接到此文件的超链接的名字。
■ nrowsperpage:指明每个页面文件中最多的记录数目。其默认值为0,即所有的返回结果记录集都将放在一个页面文件之中。当查询所返回的记录数目多于此参数指定的值时,将会产生其他的页面文件来放置超出的记录。而且这些页面文件之中包含相互的超链接地址(第一页、前一页、后一页、最后一页),可以点击这些超链接来完成在这些页面之间的跳转。
■ datachg:用来指明当表中哪些字段变化时,执行此任务来产生新的页面文件(当whentype参数为10时)。其语法格式如下:
{TABLE= name [COLUMN=name]}[,...]
■ charset:指明页面文件使用的字符集。对于中文,其值应该为'gb2312'。
■ codepage:指明页面文件使用的代码页。对于中文,其值应该为936。
对于各种文字charset和codepage的取值如下(可以通过运行sp_enumcodepages存贮过程来得到下面的列表):
Code Page Character Set 语种
708 ASMO-708 阿拉伯字符 (ASMO 708)
720 DOS-720 阿拉伯字符 (DOS)
28596 iso-8859-6 阿拉伯字符 (ISO)
1256 windows-1256 阿拉伯字符 (Windows)
1257 windows-1257 波罗的海字符 (Windows)
852 ibm852 中欧字符 (DOS)
28592 iso-8859-2 中欧字符 (ISO)
1250 windows-1250 中欧字符 (Windows)
936 gb2312 简体中文 (GB2312)
52936 hz-gb-2312 简体中文 (HZ)
950 big5 繁体中文 (Big5)
866 cp866 西里尔字符 (DOS)
28595 iso-8859-5 西里尔字符 (ISO)
20866 koi8-r 西里尔字符 (KOI8-R)
21866 koi8-ru 西里尔字符 (KOI8-U)
1251 windows-1251 西里尔字符 (Windows)
28597 iso-8859-7 希腊字符 (ISO)
1253 windows-1253 希腊字符 (Windows)
862 DOS-862 希伯来字符 (DOS)
38598 iso-8859-8-i 希伯来字符 (ISO-Logical)
28598 iso-8859-8 希伯来字符 (ISO-Visual)
1255 windows-1255 希伯来字符 (Windows)
50932 _autodetect 日语 (自动选择)
51932 euc-jp 日语 (EUC)
932 shift_jis 日语 (Shift-JIS)
949 ks_c_5601-1987 朝鲜语
874 windows-874 泰语 (Windows)
1254 iso-8859-9 土耳其字符 (Windows)
65001 utf-8 Unicode (UTF-8)
1258 windows-1258 越南字符 (Windows)
1252 iso-8859-1 西欧字符
同静态页面导出相关的还有以下存贮过程:
sp_runwebtask:用于执行由sp_makewebtask建立的静态页面导出任务。其语法结构如下:
sp_runwebtask [][@procname =] 'procname']
[,][@outputfile =] 'outputfile'
其中procname参数指明要执行的静态页面导出任务的名字,而outputfile则指明任务的输出文件。比如要运行我们在上面建立的静态页面导出任务,就可以通过下面的语句来完成:
EXEC sp_runwebtask 'test Web Page'
sp_dropwebtask:删除建立的静态页面导出任务。其语法结构如下:
sp_dropwebtask {[@procname =] 'procname' | [,@outputfile =] 'outputfile'}
其中procname参数指明要删除的静态页面导出任务的名字。而outputfile则指明要删除的导出文件。如果要删除我们在上面建立的静态页面导出任务,则通过下面的语句来完成:
EXEC sp_dropwebtask 'test Web Page', 'D:\test\cbb\ttt.htm'
SQL Server静态页面导出技术
本段文章节选自铁道出版社新出的《用BackOffice建立Intranet/Extranet应用》一书(现已在海淀图书城有售)。本书详尽地讲述了如何使用微软BackOffice系列产品来组建Intranet/Extranet应用。通过它您将掌握NT的安装和设置、使用IIS建立Web站点、通过ILS建立网络会议系统、用Exchange建立企业的邮件和协作系统、用SQL Server建立Web数据库应用、用Proxy Server建立同Internet安全可靠的连接、用Media Server建立网络电视台/广播站、用Chart server建立功能强大的聊天室、用Site Server建立个性化的邮件列表和分析网站的访问情况、用Commerce Server建立B2B或B2C的电子商务网站。此外本书还对网络的安全性进行了讨论,从而指导您建立一个更为健壮和安全的网络应用。阅读本书之后,您将发现实现丰富多彩的网络应用原来这样简单……
绝对原创,欢迎转载。但请务必保留以上文字。


静态页面导出实例分析:
下面讨论如何使用静态页面导出技术来实现我们在前面要求的各种功能。
首先,我们来看看要导出的页面文件的结构:
所有导出的页面都将被放在一个目录名为当日期的目录下。其中有两个非导出文件index.htm和show.htm文件。其作用同cbbinput目录中的default.htm和show.htm文件相类似。都是为了满足使页面能够正常显示的需要。之所以使用index.htm而不用default.htm为文件名,是因为大多数ISP提供的主页空间的目录省缺文件的名字都是index.htm。
当日的各个版面则导出为一个名为list.htm的文件。每个版面的文章题目列表则分别按顺序导出为1~n(n为当日的版面总数)个页面文件。其文件名也为1.htm~n.htm。当日所刊载的各个文章则以其id为文件名分别进行导出。在list.htm文件中,包含到各个版面页面文件的超链接。在各个版面的页面文件中,又包含到各个文章页面文件的超连接。
在出版报的主页上,还应该有一个用来显示日期的页面文件。每个日期的超链接都将与其页面文件所在的目录中的index.htm文件相对应。点击日期后,将弹出一个新的浏览器窗口。其中显示的是相应日期的报纸内容。
此外,还应当将此日各篇文章的配图文件也拷贝到此目录之下。
我们为此建立一个任务,它会在每天下午的六点执行,将当天报纸的内容导出为静态的HTML页面文件。此任务的代码如下(可以在本书配套光盘的SQLServer目录的子目录test下找到此段代码的文件,其文件名为webout.sql。它使用的模板文件也可以在此目录下找到):
use test
go
declare
@riqi varchar(20),
@filepath varchar(255),
@listfile varchar(255),
@command varchar(255)
set @riqi=left(convert(varchar(40),getdate(),20),10)
set @filepath='d:\webout\' @riqi '\'
set @command='md ' @filepath
execute master.dbo.Xp_cmdshell @command
set @command='md ' @filepath 'images'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\files\*.* d:\webout\' @riqi '\'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\files\images\*.* d:\webout\' @riqi '\images\'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\' @riqi '\*.* d:\webout\' @riqi '\'
execute master.dbo.Xp_cmdshell @command
set @listfile=@filepath 'list.htm'
execute sp_makewebtask
@outputfile=@listfile,
@query='select distinct banmian
from gaojian
where kanwu=''出版报'' and datepart(yy,riqi)=datepart(yy,getdate()) and datepart(dy,riqi)=datepart(dy,getdate())',
@templatefile='d:\test\list.tml',
@codepage=936

declare
@lists int,
@banmian varchar(64),
@filename varchar(64),
@search varchar(2000)
set @lists=0
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
fetch point into
@banmian
while (@@fetch_status=0)
begin
set @lists=@lists 1
set @filename=@filepath convert(varchar(64),@lists) '.htm'
set @search='SELECT id,timu,laiyuan
FROM gaojian
WHERE datepart(yy,riqi)=datepart(yy,convert(datetime,''' @riqi '''))
and datepart(dy,riqi)=datepart(dy,convert(datetime,''' @riqi '''))'
'and banmian =''' @banmian '''and kanwu=''出版报''order by timu'
execute sp_makewebtask
@outputfile=@filename,
@query=@search,
@templatefile='d:\test\list2.tml',
@codepage=936
fetch point into
@banmian
end
close point
deallocate point

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

declare
@dy int,
@date varchar(20),
@yue varchar(2),
@yue2 varchar(2),
@ri int,
@xingqi int,
@year int,
@outchar varchar(1600),
@tt int

create table ##daylist
(out varchar(1600))

set @yue2='00'
set @tt=0

declare point3 cursor for
SELECT distinct
dy=datepart(dy,riqi),date=left(convert(varchar(40),riqi,20),10),
yue=convert(varchar(2),datepart(mm,riqi)),ri=datepart(dd,riqi),xingqi=datepart(dw,riqi),year=datepart(yy,riqi)
FROM gaojian
where kanwu = '出版报'
order by year,dy
for read only

open point3
fetch point3 into
@dy,@date,@yue,@ri,@xingqi,@year
while (@@fetch_status=0)
begin
if @yue<>@yue2
begin
set @tt=0
if @yue2=0
insert into ##daylist
values('<TABLE BORDER="BORDER" ALIGN="CENTER"><th><tr><h2>' convert(varchar(4),@year)
'年' @yue '月份</h2></tr></th><tr><td>星期日</td><td>星期一</td><td>星期二</td><td>星期三</td><td>星期四</td><td>星期五</td><td>星期六</td></tr>')
else
insert into ##daylist
values('</tr></table><TABLE BORDER="BORDER" ALIGN="CENTER"><th><tr><h2>'
convert(varchar(4),@year) '年' @yue '月份</h2></tr></th><tr><td>星期日</td><td>星期一</td><td>星期二</td><td>星期三</td><td>星期四</td><td>星期五</td><td>星期六</td></tr>')
end
if @tt<>0
if @xingqi < 7
set @outchar=@outchar '<td><a href="' @date '/index.htm" TARGET="new">' convert(varchar(2), @ri) '</a></td>'
else
set @outchar=@outchar '<td><a href="' @date '/index.htm" TARGET="new">' convert(varchar(2), @ri) '</a></td></tr><tr>'
else
begin
set @tt=1
set @outchar=
case
when @xingqi=1 then ''
when @xingqi=2 then '<td></td>'
when @xingqi=3 then '<td></td><td></td>'
when @xingqi=4 then '<td></td><td></td><td></td>'
when @xingqi=5 then '<td></td><td></td><td></td><td></td>'
when @xingqi=6 then '<td></td><td></td><td></td><td></td><td></td>'
when @xingqi=7 then '<td></td><td></td><td></td><td></td><td></td><td></td>'
end
if @xingqi < 7
set @outchar=@outchar '<td><a href="' @date '/index.htm" TARGET="new">' convert(varchar(2), @ri) '</a></td>'
else
set @outchar=@outchar '<td><a href="' @date '/index.htm" TARGET="new">' convert(varchar(2), @ri) '</a></td></tr><tr>'
end

insert into ##daylist values(@outchar)

set @yue2=@yue
set @outchar=''

fetch point3 into
@dy,@date,@yue,@ri,@xingqi,@year
end
close point3
deallocate point3

execute sp_makewebtask
@outputfile='d:\test\daylist.htm',
@query='select * from ##daylist',
@templatefile='d:\test\rili.tml',
@codepage=936
drop table ##daylist
首先请读者通读上面的代码,以便对它有一个大概的了解。下面我们将对代码进行逐段的分析和讲解:
SQL Server静态页面导出技术
本段文章节选自铁道出版社新出的《用BackOffice建立Intranet/Extranet应用》一书(现已在海淀图书城有售)。本书详尽地讲述了如何使用微软BackOffice系列产品来组建Intranet/Extranet应用。通过它您将掌握NT的安装和设置、使用IIS建立Web站点、通过ILS建立网络会议系统、用Exchange建立企业的邮件和协作系统、用SQL Server建立Web数据库应用、用Proxy Server建立同Internet安全可靠的连接、用Media Server建立网络电视台/广播站、用Chart server建立功能强大的聊天室、用Site Server建立个性化的邮件列表和分析网站的访问情况、用Commerce Server建立B2B或B2C的电子商务网站。此外本书还对网络的安全性进行了讨论,从而指导您建立一个更为健壮和安全的网络应用。阅读本书之后,您将发现实现丰富多彩的网络应用原来这样简单……
绝对原创,欢迎转载。但请务必保留以上文字。


use test
go
declare
@riqi varchar(20),
@filepath varchar(255),
@listfile varchar(255),
@command varchar(255)
set @riqi=left(convert(varchar(40),getdate(),20),10)
set @filepath='d:\webout\' @riqi '\'
set @command='md ' @filepath
execute master.dbo.Xp_cmdshell @command
set @command='md ' @filepath 'images'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\files\*.* d:\webout\' @riqi '\'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\files\images\*.* d:\webout\' @riqi '\images\'
execute master.dbo.Xp_cmdshell @command
set @command ='copy d:\test\' @riqi '\*.* d:\webout\' @riqi '\'
execute master.dbo.Xp_cmdshell @command
set @listfile=@filepath 'list.htm'
execute sp_makewebtask
@outputfile=@listfile,
@query='select distinct banmian
from gaojian
where kanwu=''出版报'' and datepart(yy,riqi)=datepart(yy,getdate()) and datepart(dy,riqi)=datepart(dy,getdate())',
@templatefile='d:\test\list.tml',
@codepage=936
在此段代码中先定义了一些变量,用来调用存贮过程时使用。其中@riqi变量用于存放当日的日期(其格式为yyy-mm-dd);@filepath变量用于存放产生静态页面的路径;@listfile变量用于存放版面列表页面文件的路径和文件名;@command变量用于存放要执行的系统命令。
随后我们对各个变量进行赋值。并调用xp_cmdshell存贮过程来完成建立相应目录、拷贝文件等工作。xp_cmdshell存贮过程是一个用来执行NT系统命令的扩展存贮过程。其语法结构如下:
xp_cmdshell {'command_string'} [, no_output]
其中command_string参数为要执行的系统命令。而选项no_output则用来指明不输出系统命令的执行结果。
在此段代码的最后,执行未指明whentype参数的sp_makewebtask存贮过程,导出当日的版面列表页面文件。使用的模板文件为list.tml。list.tml文件的代码如下:
<html>
<head><title>出版报</title></head>
<body BACKGROUND="images/WB00703_.gif">
<script>
var t=0;
</script>
<table BORDER="0" ALIGN="CENTER">
<緂indetail%>
<tr>
<td><img SRC="images/Yellowb2.gif" WIDTH="14" HEIGHT="14">
<script>
var t=t 1;
document.write('<a HREF="');
document.write(t);
document.write('.htm" TARGET="show"><b><i><font SIZE=" 1">')
</script>
<%insert_data_here%></font></i></b></a></td></tr>
<%enddetail%>
</table></body></html>
可以看到,静态页面导出使用的模板文件同IDC技术中使用的htx文件十分相似。其中也包含<緂indetail%>和<%enddetail%>字段。所不同的是,模板文件中不使用<%字段名%>来标识字段。只是简单的使用<%insert_data_here%>来指明在何处插入结果集中的数据。如果结果集记录中包含多个字段的话,<%insert_data_here%>将按照其在记录中的顺序(即按照SELECT语句中的字段顺序)来顺序地插入数据。也就是说,每个结果记录中的每个字段只能在页面中被插入一次。如果要想在页面中多次使用某个字段,可以先将它赋给一个变量。然后再反复地使用此变量即可。
在此模板文件中有一段Java程序,其用途是为每个版面按照其顺序产生超链接。其链接分别为1.htm~n.htm,n值为当日版面的数目。
至此我们已经成功地建立了存放页面文件的目录、完成了相应文件的拷贝工作、导出了当日版面的列表文件。下面将为每个版面来产生文章列表页面文件。
declare
@lists int,
@banmian varchar(64),
@filename varchar(64),
@search varchar(2000)
set @lists=0
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
fetch point into
@banmian
while (@@fetch_status=0)
begin
set @lists=@lists 1
set @filename=@filepath convert(varchar(64),@lists) '.htm'
set @search='SELECT id,timu,laiyuan
FROM gaojian
WHERE datepart(yy,riqi)=datepart(yy,convert(datetime,''' @riqi '''))
and datepart(dy,riqi)=datepart(dy,convert(datetime,''' @riqi '''))'
'and banmian =''' @banmian '''and kanwu=''出版报''order by timu'
execute sp_makewebtask
@outputfile=@filename,
@query=@search,
@templatefile='d:\test\list2.tml',
@codepage=936
fetch point into
@banmian
end
close point
deallocate point
在此段代码中我们使用了游标。在此之前我们所使用的SQL语句都是用于集合操作的。也就是说,语句只是用来产生结果集合,或对结果集合进行分组。而要想分别对每个返回的结果记录进行不同的处理,就只有通过游标来实现了。
责任编辑:semirock