SQL Server同Index Server的結合應用3/3——選自《用BackOffice建立Intranet/Extranet應用》一書

- 中國WEB開發者網絡 (http://www.webasp.net)
-- 技術教程 (http://www.webasp.net/article/)
--- SQL Server同Index Server的結合應用3/3——選自《用BackOffice建立Intranet/Extranet應用》一書 (http://www.webasp.net/article/3/2708.htm)
-- 作者:未知
-- 發佈日期: 2003-07-11
本段文章節選自鐵道出版社新出的《用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的電子商務網站。此外本書還對網絡的安全性進行了討論,從而指導您建立一個更為健壯和安全的網絡應用。閱讀本書之後,您將發現實現豐富多彩的網絡應用原來這樣簡單……
絕對原創,歡迎轉載。但請務必保留以上文字。

6.11.2.    通過SQL Server查詢Index Server
    如果要通過SQL Server查詢Index Server,須使用OPENQUERY函數。其語法結構如下。
    OPENQUERY(linked_server, 'query')
    其中linked_server參數為連接的名稱。而query參數為要進行的查詢,它將以一個字符串的形式傳送給OPENQUERY函數。此函數返回的將是一個虛擬表,從而可以讓我們對其做進一步的查詢。
    下面的語句查找內容包含中SQL這個單詞的所有文件:
    SELECT *
FROM OpenQuery(FileSystem,
'SELECT Directory, FileName, DocAuthor, Size, Create
FROM SCOPE()
WHERE CONTAINS( Contents, ''SQL'' ) ' )
    對於Index Server的查詢,其FROM語句的語法格式於普通的SQL語句是有所區別的。其語法結構如下:
FROM [ Catalog_Name.. ] { SCOPE( [ 'Scope_Arguments' ] ) }
其中的Catalog_Name參數用於指明要進行查詢的索引目錄。由於我們在定義連接時只能選擇一個索引目錄,所以此參數在此將被省略。而SCOPE函數用於指明要進行查詢的文件所在的目錄。SCOPE函數的語法結構如下圖所示。

圖6.11.2-1SCOPE函數語法結構圖
其中DEEP TRAVERSAL OF關鍵字指明將查詢目錄中所有的文件,包括其子目錄中的所有文件。而SHALLOW TRAVERSAL OF關鍵字則指明只查詢頂級目錄中的文件,而不包括子目錄中的那些文件。如果不指明查詢的目錄深度,則默認為DEEP TRAVERSAL OF。
physical_path和virtual_directory分別為物理目錄和虛擬目錄。其中各自的含義在圖中已經標示的非常明白了,在此就不再進一步說明了。
Index Server共支持50種文件屬性,而可以用來作為查詢條件或返回結果的常用文件屬性見下表:
屬性名稱    數據類型    註釋    可否用於ORDER BY子句    可否用於SELECT語句中
Access    datetime    文件的最後訪問時間。    可    可
Characterization    nvarchar或ntext    文檔的描述或摘要,由Index Server使用。    否    可
Create    datetime    文件的創建時間。    可    可
Directory    Nvarchar    文件的物理路徑,不包含文件名。    可    可
DocAppName    nvarchar    創建文件的應用程序的名稱。如Microsoft Word 9.0。    可    可
DocAuthor    nvarchar    文檔的作者。    可    可
DocComments    nvarchar    關於文檔的註釋。    可    可
DocCompany    nvarchar    寫作文檔的公司的名稱。    可    可
DocLastAuthor    nvarchar    最近編輯文檔的用戶。    可    可
DocLastPrinted    datetime    文檔的最近一次打印時間。    可    否
DocPageCount    integer    文檔的頁數。    可    否
DocParaCount    integer    文檔的圖形數量。    可    否
DocRevNumber    integer    文檔的當前版本。    可    可
DocSubject    nvarchar    文檔的主題。    可    可
DocTemplate    nvarchar    文檔的模板。    可    可
DocTitle    nvarchar    文檔的標題。    可    可
DocWordCount    integer    文檔的字數。    可    否
FileIndex    Decimal(19,0)    文件的唯一標識。    可    可
FileName    nvarchar    文件名。    可    可
HitCount    integer    文件中的命中次數(單詞匹配查詢)。即文件中有多少個查詢條件中的單詞。    可    可
Path    nvarchar    文件的物理路徑,包含文件名。    可    可
Rank    integer    行的等級,範圍從 0 到 1000,數字越大表示越匹配。    可    可
ShortFileName    nvarchar    短文件名(8.3格式)。    可    可
Size    Decimal(19,0)    文件大小,單位是字節。    可    可
VPath    nvarchar    指向文件的完整虛擬路徑,包括文件名。如果有多個可能的路徑,將選擇最符合查詢的一個。    可    可
Write    datetime    最近一次寫文件的時間。    可    可

    可以在Where子句中使用以上各種屬性作為查詢的條件。當條件中包含全文檢索條件時,需要使用CONTAINS和FREETEXT語句,其用法同SQL Server的全文檢索相同。要注意的是,在對Index Server的查詢中,不能使用GROUP BY和HAVING子句。因為這不被Index Server所支持。
此外,在查詢的SELECT子句中,不能使用*來選擇所有的屬性。*只有在對視圖進行查詢時才可以使用。視圖實際上可以理解為從一個查詢導出的虛擬表。通過對視圖的查詢,可以實現對查詢結果的再次查詢。視圖一般應用於需要經常被其他查詢作為FROM子句中的數據源時使用。建立視圖使用CREATE VIEW語句,其語法結構如下:
CREATE VIEW view_name [(column ][,...n])]
AS
    select_statement
其中view_name為要建立的視圖的名稱,而AS子句後面的就是建立視圖的查詢語句。而此語句有以下限制:不能包含ORDER BY、COMPUTE和COMPUTE BY等子句;不能包含INTO關鍵字;不能涉及臨時表。
而column則用於為視圖中的各個字段命名。一般只有在這些字段是表達式或函數及常數時才需要為其命名。
在SQL Server中,也同樣可以使用CREATE VIEW語句來建立視圖。
下面我們通過一個例子來瞭解對Index Server查詢的全部過程。
我們將在虛擬目錄\Corpus和C:\temp目錄中查找那些作者在writer表中存在記錄且文檔字數超過5000字的文件。並返回作者的名字、文檔題目以及作者的身份。其查詢語句和具體操作過程如下圖所示。

圖6.11.2-2Index Server查詢過程
其中各個步驟的解釋如下:
1:查詢被提交到SQL Server,將分佈式查詢部分(包含在OPENQUERY函數之內的部分)傳遞給SQL Server分佈式查詢處理器。
2:分佈式查詢處理器將查詢進一步傳遞給OLE DB Provider for Indexing Service(MSIDXS),由MSIDX連接到文件系統。
3:MSIDXS分析查詢語句並向文件索引服務發出相應的命令。
4:文件索引服務從一個結合了Web虛擬目錄/Corpus和C:\Temp目錄的虛擬表中查找那些符合條件的文件並將其作為一個行集返回給MSIDX。
5:MSIDXS將行集返回給分佈式查詢處理器。
6:分佈式查詢處理器將返回的行集作為一個表同writers表進行結合查詢,並將最終結果返回給查詢提交者。
在對Index Server的查詢中,還不能使用QUANTIFIED、COMPARISON、BETWEEN、EXISTS、IN以及NULL等謂詞。因為這些都不被Index Server所支持。但是它支持兩個SQL Server所不直接支持的兩個謂詞:MATCHES和ARRAY。我們可以在對Index Server的查詢語句中使用它們。其含義和語法結構分別如下:
MATCHES:用於模式匹配,其作用同Like相近但是功能更為強大。它的語法結構如下:MATCHES (Column_Reference, ' { Grouped_Search_Pattern | Counted_Search_Pattern } ') > 0
其中Column_Reference為指定的文件屬性,其數據類型必須同後面的Grouped_Search_Pattern相匹配。
Grouped_Search_Pattern為指定的匹配模式。而Counted_Search_Pattern則用於對匹配的數量進行限定,可以有三種限定方式:
嚴格匹配:在查詢的文件屬性中包含指定數目的滿足匹配條件的字串。
至少匹配:在查詢的文件屬性中包含大於或等於指定數目的滿足匹配條件的字串。
範圍匹配:在查詢的文件屬性中包含滿足匹配條件的字串數目界於n∼m之間。
MATCHES可以使用的模式匹配符及其含義見下表:
符號    描述
*    包含指定的匹配字符串同時還包含其他0個或更多的字符。這同dir命令中使用的*十分類似。如以b開頭,以d結尾的字符串的匹配條件為b|*d。
?    包含指定的匹配字符串同時還包含其他0個或一個字符。如滿足b|?d匹配條件的字串包括bd、bad和bed等。
+    包含指定的匹配字符串同時還包含其他1個或更多的字符。如滿足b|+d匹配條件的字串包括bad、bed和bond等。
( )    用於界定模式匹配,表明在其中的是模式匹配字符條件。當條件多於一個時使用。
{ }    用於界定匹配數量,表明在其中的是模式匹配數量條件。
[ ]    用來在模式條件中指明一個字符串的範圍。
|    一個轉義符,要求在上面的每個符號前使用它。從而將其同普通字符區別開來。
    下面通過幾個簡單的例子來說明MATCHES謂詞的使用方法。
    查找文件內容中出現"SQL"三次的文件:
...WHERE MATCHES (DocText, '|(SQL|)|{3|}' ) > 0
查找文件內容中出現"SQL"三次以上的文件:
...WHERE MATCHES (DocText, '|(SQL|)|{3,|}' ) > 0
查找文件內容中出現"SQL"三次到十次之間的文件:
...WHERE MATCHES (DocText, '|(Bora|)|{3,10|}' ) > 0
當你不能確定作者姓名中包含"Pellow"還是"Pelow"時,可以使用下面的條件語句:
...WHERE MATCHES( DocAuthor, '* Pel|{1,2|}ow' ) > 0
ARRAY:用於在兩個排列(也稱為矢量)之間通過邏輯運算符來進行比較。其語法結構如下:
Column_Reference Comparison_Operator [ ALL | SOME ] ARRAY [ Array_Elements ]
其中Column_Reference用於比較的文件屬性,可以是多個屬性。但是要求其數據類型同後面的Array_Elements相匹配。
Comparison_Operator為比較運算符,它可以是=、!=(不等於)、>、=>、<、<=。
Array_Elements用於指明用於進行比較的排列,其必須用"[]"括起來。空的排列也是允許的,比如下面的查詢也是合法的。
SELECT foo FROM SCOPE() WHERE bar = ARRAY[]
ALL和SOME則用來指明對Array_Elements使用不同的比較方式。對於All,將會對左側排列中的每個元素同右側排列中相應的元素進行比較。比如下面的表達式對於ALL,表達式結果為假:
[1,2,3] > ALL ARRAY [1,2]
而對於SOME,則只要在左側排列中有一個值同右側排列中所有的值比較復合條件即可。因此下面的表達式對於SOME,其表達式結果為真:
[1,2,3] > SOME ARRAY [2,1]
因為在左側排列中的3,比右側排列中的2和1都大因此返回值為真。
如果不指明ALL或SOME,將會按照從左至右的順序對表達式左側排列中的元素同右側中相應的元素進行比較。而一旦兩者不同,將直接返回比較結果而不再繼續進行其他元素的比較。而如果所有比較的值都相等,則根據排列的勢來決定最後的比較結果。因此下列表達式的值都為真。
ARRAY [2,3,4] > ARRAY [1,2]
ARRAY [2,3,4] > ARRAY [1,2,3]
ARRAY [2,3,4] > ARRAY [1,2,3,4]
ARRAY [2,3,4] > ARRAY [1,2,5]
ARRAY [2,3,4] > ARRAY [2,3,3]
ARRAY [2,3,4] > ARRAY [2,3]
ARRAY [2,3,4] < ARRAY [2,3,4,5]
ARRAY [2,3,4]!= ARRAY [2,3,4,5]
下面通過幾個例子來說明ARRAY謂詞的使用方法:
查找所有文件屬性為"存檔"的文件:
...WHERE attrib = ARRAY [ 0X820 ]
查找所有文件屬性為"存檔"或"壓縮"(針對於NTFS文件系統)的文件:
...WHERE attrib = SOME ARRAY [0X820 ]
查找矢量值為[10,15,20]的ActiveX文檔:
...WHERE vectorprop = ARRAY [10, 15, 20]

webasp.net