我们将这个HTML代码存储在字符串变量strHTML中: Public
Function ShowSearchFrame() As String "~~~~~ Local variables Dim strHTML As
String "===== Search input field strHTML = SearchInputField End
Function
POST当然是这两种方法中较好的一个,因为它在HTTP
头文件中隐藏了输入的文本并且允许更长的值。但是我们的例子中,是一个短的文本值,? T
也能允许通过将一个查询字符串附在任何URL的结尾来调用方法。它还有一个好处就是允许浏览器缓存查询结果,因为在进行GET
时,缓存在完整的URL上工作。这样就可以快速访问每个搜索页面,并且在后来离线浏览。
当访问者输入"component"
作为他们的文本输入时,我们的表单发送下面的URL和查询字符串: SearchPage.asp?Src=component 你还可以从任何站点将这一声明作为一个连接包含在一个HREF标记内--SearchPage.asp
文件不需FORM标记就能工作。 以下是完整的SearchInputField 函数,它生成以上的HTML 代码和浏览器输入控制: Private
Function SearchInputField() As String Dim strHTML As String "~~~~ Search
input form start strHTML = strHTML & "< FORM NAME=""SearchForm""
METHOD=""GET"" ACTION=""" _ & mstrSearchFrameURL & """ TARGET="""
& mstrSearchFrameName & """ >" "~~~~ Search input field strHTML =
strHTML & "< INPUT TYPE=""TEXT"" NAME=""Src"" MAXLENGTH=""50""" _ &
"SIZE=15 VALUE=""" & mobjRequest.QueryString("Src") & """ >" "~~~~
Search input button strHTML = strHTML & "< INPUT TYPE=SUBMIT
VALUE=""Search"" >" "~~~~ Search input form end strHTML = strHTML & "<
/FORM >" SearchInputField = strHTML End
Function 请注意我们是如何在HTML代码的连接片段内连接属性程序变量来使用它们的。还要注意HTML标记内要求的单引号(")
是如何被双引号("")
引用的,这样就可以避免VB把它作为一个字符串常量的开头或结尾而产生错误。 还有一个需要注意的是,在INPUT标记内被设置为VALUE的变量。它从查询字符串mobjRequest.QueryString("Src")
中得到它的值,聪明的读者会认出它就是标记本身的名字: VALUE=""" &
mobjRequest.QueryString("Src") 这个自引用查询字符串将在它的文本域内显示发送时在域中键入的任何文本。由于在文本输入域中键入"component"
将把?Src=component附在URL的结尾,INPUT
标记的值将在输入文本框中显示Src的值。
回到ShowSearchFrame
方法第二部分 回到我们的ShowSearchFrame 方法,它是在SearchInputField
方法中被调用的,我们将返回的HTML代码存储在strHTML变量中。但是在我们将它发送给浏览器之前,必须要确定访问者是否已经输入了一个搜索查询文本让我们在搜索数据库过程中使用。 这是通过校验Src
查询字符串变量是否为空实现的。如果为空,就通知访问者现在他们可以输入查询字符串了。当访问者进入一个搜索站点,连接到一个没有Src
查询字符串的网页时通常就会看到这样的提示。 ShowSearchFrame 调用 SearchInputField
方法并将HTML输入控制代码存储到strHTML 变量后,我们要查看一下这是不是一个新用户或查询请求: "===== Search input
field strHTML = SearchInputField If mobjRequest.QueryString("Src") = ""
Then "~~~~~ No query was entered strHTML = strHTML & "Enter a
query" Else "[Search code here] End
If
如果没有名为Src的查询字符串,连接来自我们的组件以外,我们可以将一个介绍性的信息附在strHTML
代码上(从这个组件发送一个空查询也会产生同样效果): strHTML = strHTML & "Enter a
query" 现在我们的第一个HTML代码已经完整了,我们将它发送给 IIS在访问者的浏览器上显示: Else "[Search code
here] End If "~~~~~ Send html code to IIS for delivery to visitors browse
r mobjResponse.Write (strHTML ) 产生下面的显示:
访问者输入了要组件搜索的文本以后,以上的条件If 语句就会发现VBmobjRequest.QueryString("Src")
变量不为空,分支控制逻辑就会流向选择的Else 部分。然后连接到数据库并在数据库中搜索匹配的Title 和 Text 域。
因为我们要搜索一个Access Memo 型域,或者说是SQL 服务器文本型域,我们不在SQL声明内使用LIKE
语句。相反,我们通过以下的SQL字符串返回一个记录集: SELECT Title, Text, URL FROM
SearchTable 可以用一个帐号群ID、一个典型范围或者在过滤表中有相关内容的任何类别来限制初始查询。 由于SQL声明恢复每个记录,我们就很快地搜索Title和
Text 域寻找与我们的访问者所提交的文本查询字符串相匹配的内容。这个字符串的搜索用VB
InStr声明来实现。如果找到了匹配,并且我们在导航分界线的范围之内,就将标题和URL放置在动态字符串数列里。
Public
Function ShowSearchFrame() As String "~~~~~ Local variables Dim strHTML As
String Dim astrTitleArray() As String Dim astrURLarray() As String Dim
intRecordsDisplayed As Integer Dim intRecordsMatched As
Integer 声明了两个动态字符串变量和两个整形变量之后,就可以将它们传递给第二个方法。GetRecords
函数用数据库中的标题和URL的值来填充字符串数列。用数列中条目的个数设置intRecordsDisplayed 变量。intRecordsMatched
变量中保存与访问者查询字符串相匹配的记录数。我们使mintRecordsSearched
成为一个属性程序,可从ASP主机文件中读取。尽管我们不在这个组件中使用它,用户可能想知道共搜索到多少条记录。
这是ShowSearchFrame
方法中的方法调用。记住,GetRecords函数是有条件地被调用的,当有来自用户的搜索查询,并且在SearchInputField方法之后: If
mobjRequest.QueryString("Src") = "" Then "~~~~~ No query was
entered strHTML = strHTML & "Enter a query" Else "[Search code
here] mintRecordsSearched = GetRecords(astrTitleArray(),astrURLarray(),
_ intRecordsDisplayed, intRecordsMatched) End If
GetRecords
函数 现在我认为对声明和传递方法变量的特殊方法的细节已经介绍得够多了。对于GetRecords方法的解释将主要是此方法的一般功能方面。 如果你使用的是VB5的话,就需要安装Service
Pack 3 以获得对ADO 的引用来使这些代码工作。 首先要注意在声明之后,代码有一个错误控制声明。 Private Function
GetRecords(astrTitleArray() As String, astrURLarray() As _ String,
intRecordsDisplayed As Integer, intRecordsMatched As _ Integer) As
Integer "~~~~~ LOCAL VARIABLES Dim intCount As Integer Dim
intRecordsSearched As Integer Dim strHTML As String Dim strSearchHold As
String Dim strTitleHold As String Dim strTextHold As String Dim
strURLhold As String Dim recSearch As New ADODB.Recordset Dim objCmd As
New ADODB.Command Dim objConn As New ADODB.Connection Dim strSQL As
String On Error GoTo ErrorCode 如果在使用数据库时发生了错误,控制就在函数结尾处传递一个ErrorCode
标志。 下面的6个声明用Data Source Name(数据源名)打开到数据库的连接、启动一个处理、设置SQL字符串、将SQL
字符串分配给ADO命令对象、告诉命令对象等待一个SQL字符串、设置到命令对象的连接。 在这里我使用的处理是为了示范,而且因为它在转入命令之前用二进制存储代码,这样可以提高数据库处理的速度: "~~~~~
Open the connection with a data source name objConn.Open
"SearchExampleDSN" "~~~~~ Begin the transaction (only for speed in this
case) objConn.BeginTrans "~~~~~ Store the SQL command in a
string strSQL = "SELECT Title, Text, URL FROM SearchTable" "~~~~~ Set the
Command object to the SQL string objCmd.CommandText = strSQL "~~~~~
indicate that the command is a SQL string (for speed) objCmd.CommandType =
adCmdText "~~~~~ Set the Connection object to the Command object Set
objCmd.ActiveConnection =
objConn 一旦我们用命令对象得到了所需要的打开记录集的连接,我们就设置: "~~~~~Open Recordset with the
above Command settings recSearch.Open
objCmd 在继续进行搜索之前,需要验证我们确实向搜索返回了一些记录。如果没有返回记录,记录集就既是在开头也是在结尾: If
recSearch.EOF And recSearch.BOF Then "~~~~No records were returned by the
SQL GetRecords = 0 但是,如果SQL声明返回了一些记录,就需要设置一些变量确保记录集处在开头:
Else "~~~~Initialize Procedural Variables intRecordsMatched =
0 intRecordsDisplayed = 0 intRecordsSearched = 0 mintSearchStart =
CInt(mobjRequest.QueryString("Start")) If mintSearchStart = 0 Then
mintSearchStart =
1 recSearch.MoveFirst 随着不同的整数计数器的增加,我们在记录集中循环,并将数据库中的标题、文本、URL数据存储在本地字符串变量中: "~~~~Loop
through the recordset Do While Not recSearch.EOF "Increment the total
number of records to be searched intRecordsSearched = intRecordsSearched +
1 "~~~~~ Store the database field data in temparary strings strTitleHold =
recSearch.Fields("Title") strTextHold =
recSearch.Fields("Text") strURLhold =
recSearch.Fields("URL") 连接文本和标题字符串后,从头至尾搜索字符串,首先将字符串变成大写字母,然后把我们的查询字符串片段也变成大写字母进行搜索: "~~~~Concatenate
the Title and URL into a String to Search strSearchHold = strTitleHold &
strTextHold "~~~~~ Determine if the database record meets the visitors
query If InStr(UCase(strSearchHold),
_ UCase(mobjRequest.QueryString("Src"))) Then "~~~~Increment the number of
records that match the visitor"s query intRecordsMatched = intRecordsMatched
+ 1 如果我们的记录数据包含了查询字符串,就必须要确定它是否在导航列表界限范围内。这是一点技巧, "Determine if records
are within Start/Stop display range If intRecordsMatched >= mintSearchStart
And _ intRecordsDisplayed < mintMaxSearchReturn
Then 这个声明使用了mintSearchStart
变量,导航条把它作为一个查询字符串来获取,然后查看一下列表页是否达到了它的最大容量,而这个最大容量是由mintMaxSearchReturn变量决定的。如果通过了测试,就将控制传递给动态数列声明。 每次传递动态数列保存内容之后,调整其大小。 "~~~~Increment
number of records to display intRecordsDisplayed = intRecordsDisplayed +
1 "~~~~Store Title in title array ReDim Preserve
astrTitleArray(intRecordsDisplayed) astrTitleArray(intRecordsDisplayed) =
strTitleHold "~~~~Store URL in URL array Redim Preserve
astrURLArray(intRecordsDisplayed) astrURLArray(intRecordsDisplayed) =
strURLHold End If End If<