線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3867
推到 Plurk!
推到 Facebook!

深入ADO

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-10-19 14:17:09 IP:61.221.xxx.xxx 未訂閱
深入ADO -------------------------------------------------------------------------------- Active Data Objects結合了OLE DB的普遍性質—那就是在諸如RDO和DAO模型中可以找到的易於使用的 特性.ADO包含了所有可以被OLE DB標準介面描述的資料類型.換而言之,ADO是可擴充的,不需要對你的 部件做任何工作. 資料的訪問和操縱是任何實際的應用程式的一個固有部分.對於資料來說,無論它是否是關聯式的,無論 它是否存在一個DBMS,也無論它的存儲平臺是什?,資料就是資料—一個文件沒有必要一定是給定的二進 制格式. 開發者群體需要具有簡單介面的現代的開發工具以快速訪問資料.微軟對此問題的回答是Universal Data Access(UDA通用資料訪問)體系結構,對此,Stephen Rauch的文章 “Manage Data from Myriad Sources with the Universal Data Access Interfaces”中有詳細的闡述(MSJ,1997年9月).簡單的 說,UDA是一種將OLE DB應用於實際的理論.所有的都被指向一個資料源—一個試算表,一條電子郵件 消息,或一份AS/400文檔—由OLE DB介面過濾並以一種通用的格式表示,這樣應用程式能總是以同樣的 方式對資料進行訪問.位於OLE DB上的並處理來自應用程式的調用的中間層被稱作Active Data Objects (ADO).它是編寫針對帶有OLE DB提供者的任何類型的資料源的推薦標準. 圖 1 OLE DB 讓我們仔細看看Visual Studio 6.0所帶來的ADO 2.0的新特性.我將向你展示如何用Visual Studio 6.0 套件來編寫ADO.我將集中於Java語言的Windows Foundation Classes(WFC)的和Visual Basic的內置的ADO 支援,對於Visual C 和InterDev將略微提一提. ADO概述 ADO是一個物件模型,它結合了OLE DB易於使用的特性以及在諸如Remote Data Objects(RDO)和Data Access Objects(DAO)的模型中容易找到的通用特性.ADO是一個可以通過IDispatch和vtable函數訪問 的COM自動化伺服器.最重要的是:ADO包含了所有可以被OLE DB標準介面描述的資料類型.換而言之, ADO物件模型具有可擴展性,它不需要你對自己的部件做任何工作.通過通常的ADO編程介面,你可以可 視化地處理所有的事,即使那些記錄集的資訊的格式是你從來沒有想到過會見到的. ADO在其實際運行中得到了很高的評價,記憶體覆蓋,線程安全,分散式事務支援,基於Web的遠端資料訪問. 作?Microsoft UDA策略的一部分,ADO試圖成?基於跨平臺的,資料源異構的資料訪問的標準模型.隨著 時間的流逝,它將取代其他模型.ADO集中了RDO和DAO的所有最好的特性,並將它們重新組織在一個同樣 可以提供對事件的充分支援的略微有點不同的物件模型中.如果你想深入的鑽研一下Microsoft的資料 訪問技術之間的不同,你可以看看 “Data Access Technologies”,這是由Robert Green寫的MSDN的 關於技術性方面的文章. 將你當前的基於RDO的系統移植?ADO的不需要對系統的完全的重構,但它也不是件微不足道的事情.移 植系統的難度和複雜性比RDO和ADO的差異大.移植?ADO是很有價值的,但是我建議如果不是絕對必要 的話請你不要這樣做. 從企業的觀點來看ADO UDA給Windows DNA(Distributed Internet Applications分散式互連網應用程式)體系結構以一個資料 訪問和存取的機制.?進一步瞭解UDA,你可以看 “Say UDA for All Your Data Acess Needs,”該文 是由Aaron Skonnard寫的(見Microsoft Interactive Developer,1998年4月). 即使是跨了多個硬體平臺,任何一個分散式企業系統都有多個資料源,包括Microsoft Access資料庫, 試算表和SQL Server表.最近,我參加了一個異構的圖像資料庫的研究,其內容包括:SQL Server表 (包括圖像及其描述),通過與名字相關的ASCII碼和Word文檔對圖像進行分類索引,所有者文件中既 有圖像又有文本.當你需要對付這樣的工程時,你會開始認識到統一的方法和物件公共集的重要性了. 我曾經見過在相關的工程中使用不同的訪問資料方法的開發團隊.這種情況是經常發生的,這是因? 其中一個團隊相當早的提前對子專案進行了開發,或者由於它們繼承了原來的一些代碼,或出於更簡 單的原因,即這些工程只是部分相關,它們之間的公共部分是底層的資料,或者可能是買主.所以這樣 就出現了一個團隊用RDO進行資料操作,而另外一個團隊用ADO.這樣的事是常常發生的:即類似的代碼 被重復開發了兩次(或更多),一次是RDO的,一次是ADO的.在工程間的公共層就成了物理資料存儲了(見圖2). 圖2 資料訪問技術 在ADO之前的RDO是一種增加DAO的客戶/伺服器能力,以提高其性能和可擴充性的當然的方法.根本上說來, RDO是一種位於ODBC API的上層的簡便的封裝.它揭示了了DAO資料物件模型中的許多東西,但它缺乏進行 資料訪問的Jet引擎.雖然這將予ADO更快的速度,但它沒法利用該引擎的許多特性,而且它只能訪問關係 型的資料庫. ADO 2.0的思想就在於:?不同的應用程式訪問相同的資料源創建一個更高層的公用層.如果你比較圖1 和圖2,你應該會明白我的意思.儘管存在資料結構和組織間的物理位置的不同,編程的介面應該是一樣 的.?了找出RDO和ADO之間的更多的不同,我建議你閱讀Bill Vaughn寫的非常好的一篇文章 “Exploring ActiveX Data Objects from an RDO Point of View,"你能在MSDN的技術性文章部分中找到它.ADO的出 現並不意味著RDO的結束.實際上,微軟承諾在可以預見的將來繼續支援RDO. ADO 2.0有什?新特點? 對於ADO1.5以前包括1.5的版本來說,從功能的角度來看RDO和ADO不是完全相等的.等同就意味著你可 以通過這兩種方法解決同樣的問題;它不是指存在重命名的或者優化的功能相同的物件.因此,移植到 ADO不是一個簡單的事情.從另一方面來說,一旦你熟練掌握了RDO或DAO技術的話,學習ADO是件相當容 易的事情. ADO 2.0的新特性包括事件處理,記錄集的延續,分層目錄結構指標和資料成形,分散式事務處理,多維 資料,遠端資料服務(RDS),以及對C 和Java的支援的增強.在鑽研一些Visual Basic代碼的時候將會 見到所有的這些特性.當使用Visual J 時,我將舉例說明新的Windows Foundation Classes(WFC)是 如何支援ADO的.ADO的最讓人激動的是在Visual Studio 6.0中的任何開發工具中你都可以找到對它的 充分的支援. ADO快速教程 ADO物件模型是由相對數量較少的物件組成.不象RDO物件模型,每個主要的ADO物件都能被個別的被創建. 這就意味著,舉例說吧,你不需要在創建有效的記錄集物件前創建一個連接. Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset cn.Open "Biblio" rs.Open "select * from titles where title like '%h'", cn ADO 2.0物件是Connection,Command,Parameter,Recordset,Field,Error和Property.ADO物件模型也包 括四個類集:它們分別是一套相關的Error,Parameter,Property和Field物件.讓我們來看看每個物件的 主要特性. Connection物件提供連接,該連接連接的程式中存有它正在訪問的資料源.屬性允許你定義:連接串,命令 執行以及連接?動的間隔時間,資料提供者,(無論臨時表位置是應該在用戶端還是在伺服器端),和對於 資料的訪問許可權.方法有關於如下功能的:執行命令,打開和關閉一個連接和管理事務. 在許多地方你可以指定你想使用的提供者:通過Provider屬性,在連接字串中,或者甚至通過Open方法. 選擇你最喜歡的實現方式,但要保證你沒有?同樣的連接指定多個的提供者.缺省的提供者(當 你沒有指定你自己的提供者的情況下)是MSDASQL,針對ODBC的Microsoft OLE DB提供者. Command物件定義了一個SQL聲明,一個存儲過程,或任何其他的你可能想讓提供者執行的關於資料的操 作.Command的屬性有:當前連接,最大允許執行時間和參數集.一個參數就是你將它作?參數傳遞給命令 的值.在這些屬性中用以區分一個參數的屬性有:方向(輸入,輸出,或者兩者都有),類型當然還有它們的值. 記錄集物件也許是最典型的ADO物件,然而它是最複雜的當中的一個.它表示命令執行的結果,並且它大 多是以資料庫的記錄集的形式給出.一個記錄集是由以行和域的形式表示的資訊組成.它不一定非要映射 成關係型數據庫的記錄.實際上,如同我早些時候解釋的那樣,ADO是基於OLE DB並且能被用來視覺化地訪 問任何資料源中的資料,這資料源包括非關聯式的資料庫.記錄集提供了緩衝能力,它接受資料的變化,並 且將這些變化以批次處理的方式傳給伺服器.你可以瀏覽並對記錄集的內容分類,如同列舉和提取行.你也 能通過如:刪除,添加和刷新操作等任何方式修改資料.記錄集存在跟連接的嚴格的關係,但是這不意味著 你總是需要一個打開的連接來獲得一個記錄集.你也可以按如下方式進行: Dim RS As New ADODB.Recordset sql = "select * from authors" RS.Open sql, "Pubs" 既然Connection實際上是資料和命令傳送的通道,所以該物件仍然被創建了,除了一個名字叫做 Recordset.ActiveConnection的屬性外,它是不可見的並工作在後臺. Field物件是一列同類的資料.它提供了一種這樣的編程介面,即能讓你可以對單個單元的值以及基本 的特徵如:類型和大小進行讀和寫.所有給定記錄集的Field物件形成了一個Field集.如我將在後面向 你說明的, Fields集隱藏著一個引人注目的特性,它將再次證明Recordset物件的靈活性. 最後是Property物件.每個物件都有屬性.提供的使用了ADO的物件可能是各種各樣的.但不存在這樣一 套屬性即包含了所有可能的OLE DB提供者的靜態的屬性.因此,任何一個ADO物件都有靜態和動態的屬 性.第一套屬性集:包括Name,Type,Value和Attributes,都可以通過如下的語法來訪問: obj.PropertyName 最開始的三個屬性都是自我說明性的.Attributes是一種數位式的描述符,它是以按位的跟提供者的能 力有關的一些預定義的屬性組合.(它類似於COM伺服器的元件分類). 動態屬性是跟潛在的提供者類型相應的.它們被歸進Properties集合,並可以通過名字查詢. obj.Properties("propName") The New Recordset Object ADO 2.0包括一些新的功能(見圖3).現在可以通過GetString方法把記錄集扁平化變成一個字串. Set Variant = recordset.GetString( StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr ) 所有的參數都是可選的,如下代碼段所示: Dim RS As ADODB.Recordset Dim CONN As ADODB.Connection Set CONN = CreateObject("ADODB.Connection") CONN.Open "PUBS" sql = "select * from authors" Set RS = CONN.Execute(sql) MsgBox RS.GetString(, 10) RS.MoveFirst 這個常式連向大家熟悉的SQL Server PUBS資料庫,將所有的作者名字提取進一個記錄集中,然後將 它的最開始的10行拉直變成一個字串.除了在Visual Basic中外,由GetString返回的值是一個 BSTR類型的變數結構. 在調用GetString時,你可以以相當大的自由度來通過指定參數來安排資料的格式.例如:你可以改變缺 省的行和列的分界符並選擇只提取指定數量的行.目前,StringFormat參數的值只能是adClipString, 它是StringFormatEnum 列舉的唯一的成員.adClipString的值是2,它表示相繼的參數是有效的,庫 應該把它們考慮進去.NumRows是將從當前的位置開始提取的行數.NullExpr參數提供了一個選擇性 的字串,以便在記錄集中遇到了NULL值時用該字串來取代它以進行顯示. GetString方法是ADO中的對應著RDO中的GetClipString的部分.在使用GetString時應該注意一些事 情:首先,該函數返回扁平的資料.沒有輸出關於結構和描述標識的資訊或者是任何類似於類型表一類 的東西.結果是,GetString可以用來進行單向的資料傳送,而且沒有什?方法可以讀回這種類型的字 符串.第二,GetString向前移動記錄指標,如果你要進行進一步的處理,就把它移回來.你也要記住缺省 情況下該方法是輸出整個記錄集.這就意味著你你不用擔心當前的記錄是個無效的記錄. ADO 2.0的記錄集物件中還有些其他的不大的改變.一個是ActiveCommand屬性,它返回源於給定的記錄 集(如果有的的Command物件. ADO類型庫定義了ActiveCommand作?一個一般類,而不是Command物件, 所以IntelliSense模組(包含於所有的Visual Studio 6.0?品中)在寫一些使用屬性的代碼時,對你 沒有用處.如果你添加如下的一行. MsgBox RS.ActiveCommand.CommandText 到前面的代碼段中,你將能得到?生該記錄集的SQL聲明的原文. select * from authors 書簽 書簽是任意的值,它可以唯一地標識記錄集中的一行.在你需要將一個引用存儲到特定的記錄時, 你通常需要使用書簽.如你可能猜到的那樣,如果你通過標準的Clone方法克隆一個記錄集,那?書 簽就被複製了.源於不同的資料類型的ADO提供的書簽有微小的差別.如果記錄集的行總是一個資料 庫記錄,那?書簽就可能是記錄的排列值.該定義應該是絕對一致的,因此你可以通過簡單的算術操 作來比較書簽. 然而,記錄集的來源可以是任何地方, 它包含的資料也可以定址到不同的物件.此外,ADO編程者不需 要知道資料的內部結構.他或她僅僅是通過由行和域組成的介面來進行利用它的.讓我們來看一個例子. Microsoft Active Directory Service Interfaces (ADSI)是起到的是一個OLE DB提供者的作用.因 此,它公開了ADO不同種類的物件:從Windows NT或Novell目錄服務到任何Lightweight Directory Access Protocal(LDAP)—可塑的目錄服務.另外,整個ADSI體系結構在跟任何提供對其他的目錄的訪 問的服務的提供者相比時像是個無聲的客戶那樣進行工作.除了這些物件執行?所周知的和預定義的 編程介面,這就是說,ADSI它自身是這?一個公開的物件即它不知道對於任何ADO應用程式的細節. 有一個書簽是用來標識這些物件中的一個.ADO應用程式和可能的諸如ADSI這樣的提供者都並不知道 它.書簽必須由提供者直接並且完全地管理.ADO通過OLE DB的IrowsetLocate介面處理書簽.如果提供 者支援書簽,它必須恰當的執行該介面. Dim vBookmark As Variant RS.CursorLocation = adUseClient vBookmark = RS.Bookmark . RS.Bookmark = vBookmark 這代碼說明了在代碼中正確使用書簽的方法.使用支援書簽的指標類型是件重要的事情.書簽是 個可讀寫的屬性,你可以賦給它以任意值,包括連續的字元. RS.Bookmark = "Hello, world" 如果你想在Visual Basic 6.0運行時應在用程式的書簽所用的參數有問題時向你發出消息進行提 示.但終究書簽的實際值應該總是對用戶的應用程式是不可見的. 如果你需要比較書簽,你必須使用ADO 2.0中公開的Recordset物件提供的CompareBookmark函數.該 函數和Bookmark屬性自身是直接映射到IrowsetLocate函數上.特別是介面的定位方法如:Compare, GetRowsAt和GetRowsByBookmark,其名字具有自解釋性.圖4顯示了這世界上用到了記錄集物件的所 有新特性的最簡單的Visual Basic代碼. 記錄集已經濾過了在ADO 2.0前的能力,但是2.0版還添加了查找和分類特性.基本上說來,Sort屬性 影響了記錄集樹被訪問的方式和被遍曆的行的順序.Filter屬性決定哪些行是對用戶可見的.使用的 遮罩由一列布林項或是由書簽陣列給出.你也可以用通配符.最後,Find方法基於查找變址域來檢索 一行.Find方法的語法是: Find (criteria, SkipRows, searchDirection, start) 查找的準則是一個按如下格式的字串: < Field Name> < operator> < Value> 所有的布林操作符除Like外都是可能的.準則字串舉例如下: City = 'Redmond' and Name Like 'Bill*' 這裏也存在一些嚴格的語法要求.日期值必須附上一對#字元,單引號必須包圍字串. Find命令行允許你在開始查找之前跳過給定數目的行.初始位置(和那個你開始跳的位置)就是 Start參數.searchDirctiion決定了查找是自頂向下還是自下到上的.你可以做一些事來加快查找 處理的速度.首先,?記錄集設定adUseClient指標,將你想檢索的域的Optimize 動態屬性設定True. FieldName.Properties("Optimize") = True 這種方式,可以更快的檢索和訪問域的內容.注意Optimize不是提供者的屬性.它只是在ADO內部定義 和使用的.該屬性僅在asUseClient指標被設置時被添加到Properties集合中. 記錄集的延續和緩衝 幾個月前,一個讀者給我發了個EMAIL,這裏面有個很奇怪的問題.他說 “我喜歡象記錄集這樣的 結構,並且我在任何時候都用它們.ADO記錄集可以用來進行對資料的緩衝而不需要涉及到資料庫 連接或者,甚至OLE DB提供者?”我迅速對此回答: “不,我認?你不能這樣做.記錄集無論如何都 需要一個連接.” 通過更進一步的思考,我覺得他說到了最重要的問題上.ADO記錄集是個靈活的,最優的資料結構.它 們能跟OLE DB資料庫很好的工作,但是遺憾的是你並不能在任何你需要一個強大的使用方便資料結 構的時候使用它們.但這裏有個好消息.ADO 2.0給你提供了針對這一問題的新特性.Field集提供了 相當新的Append方法,它能在最初就創建一個記錄集. Dim RS As New ADODB.Recordset RS.CursorLocation = adUseClient RS.Fields.Append "Name", adBSTR RS.Fields.Append "City", adBSTR RS.Open RS.AddNew RS!Name = "DinoE" RS!City = "Redmond" 這裏是一個ADO記錄集,它就沒有資料庫連接和OLE DB的概念.ADO記錄集總歸是個獨立的物件了.要 緊的是你所選擇的客戶指標以及將你的新的域添加到記錄集的Fields集中去.Append方法需要兩個 非選擇性的參數:功能變數名稱和類型.如果你想要字串的話那就用adBSTR. 如果是這樣的話,想象使用它的應用程式是個直接的辦法.如:你可以寫代碼讀你的老的所有者文件 並將它們的資料轉到記錄集中. 這只是一個由磁片文件創建記錄集的方法.ADO 2.0增加了對記錄集的延續性的支援.實際上,你有了 個名?Save的新方法,它帶有兩個參數:輸出檔案名和資料格式. Dim rs As New ADODB.Recordset rs.adUseClient rs.Save "c:\demo.rst", adPersistADTG 目前,只有adPersistADTG(也就是零)是允許的.只有打開的記錄集才能執行存儲.存儲的資料也可 能會受你所使用的篩檢程式的影響.注意在記錄集關閉前該方法不會關閉文件的.在這中間,文件是作 ?唯讀方式訪問的.這使得ADO應用程式用Save方法來創建平行且延續的緩衝變得更容易了.如果該 文件已經存在了,Save方法返回一個錯誤,並準備執行一個工作環境.而且,該方法將當前行的位置 移到第一個記錄處.它將所有與記錄集相關的東西(包括資料和和圖表)都存到磁片上.然而,它並不 存儲連接和命令資訊.這將Save和GetString區分開來,並使得應用程式能載入先前存入的記錄集. 使用的方法是: rs.Open "c:\demo.rst" 再次說明:使用用戶端指標對於你來說是重要的. 非同步獲取和事件處理 ADO 2.0也可以讓你以這樣的方式執行命令:即以非同步方式獲取資料.這發生在調用Open方法的語法中. recordset.Open Source, ActiveConnection, CursorType, LockType, Options 跟通常一樣,Source參數被指定一個有效的SQL字串(甚至可能是一個被存儲的過程的名字),一個先 前被存儲的文件的名字,或者是一個Command物件.Options參數限定命令,並且可能影響提供者處理它 的方式.特別是它可以設定值?adExecuteAsync或adFethchAsync.adFetchAysnc意味著Source命令必 須是以非同步的方式執行,也就是說,該方法是立即返回的並且提供者在操作結束時啟動一個事件.就另 一方面來說,adFetchAsync使得第一塊中的那些行被同步地取出(跟通常一樣).其大小由記錄集中的 CacheSize屬性中所存的值來決定.剩下的那些行被非同步的載入. 當一個軟體以非同步的方式運行時,平臺應該提供一種方式使得用戶知道它什?時候結束.對於這問題 有不同的實現方法,Platform SDK使用的是同步物件,Microsoft Internet Explorer Remote Scripting 使用的是回調函數.ADO選擇的是第三種方法,也許對RAD編程者來說是最合適的一種方法:事件. 這當中有兩類事件:與Connection物件相關的事件(ConnectionEvent介面)和屬於Recordset物件的 (RecordEvent介面)(見圖5).在許多情況下你的程式將會在特定的操作發生的前後被通知.在一個 操作發生後引發的事件總是伴隨著一個Error物件用以描述操作的結果.在操作前引發的事件使得 你可以控制下一步的指令的參數.可能到達你的應用程式的事件會太頻繁.通過正確地設定一個事件 的Status參數,你可以避免更進一步的通知. WillChangeField cFields, Fields, adStatus, pRecordset CFields參數是在下一個Fields陣列中的Field物件的數目.Fields包含著帶有挂起的變化的Field對 象.相關的記錄集是通過pRecordset參數維持的.adStatus是一個類型EventStatusEnum物件,它的值 通常設?adStatusOK.現將它設?: Set adStatus = adStatusUnwantedEvent 如果你不想再要這些通知. 處理ADO事件可能是容易的,這將取決於你所使用的語言.如同你可能猜到的那樣,用Visual C 時你 應該從庫中得到連接指標並調用它的Advise方法.這要求你在你的代碼部分有相當大的編程量,但將 給你提供很多靈活性.實際上,你可以定義一個簡單的處理多個物件引發的事件處理.另一方面,所有 輸出介面中的方法都必須被執行,即使是用最簡單的語句也行: return S_OK; 與Visual C 相比,Visual Basic 和Visual J 就節省了你一些工作.特別是Visual Basic要求你? 每個物件都寫相應的事件處理,這是由於事件處理過程是基於名稱的.使用WithEvents關鍵字是在 Visual Basic中獲取事件的最好方法.(如果你用Visual C 的話,WithEvent所做的將比你用 Visual C 實現的功能可能有些不同) Visual J 遵循的是略微有所不同的實現方法:它是源於Java語言的基於Listener的事件模型. 一般說來,你需要定義一個類執行輸出介面並將這個類附在引發事件的類的實例上.這是最底限 度的要求. 通過對ADO 2.0內置的支援,WFC將它極大地簡化了.它用起來跟用Visual Basic一樣 簡單,但遠比Visual C 簡單. ConnectionEventHandler handler = new ConnectionEventHandler(this,"onConnectComplete"); 先前的片段在ConnectionEvent介面中定義了一個類以執行onConnectComplete事件.接著你將如 下的 “Listener”函數添加到物件的事件處理中. Connection conn = new Connection(); conn.addOnConnectComplete(handler); 於是,對於同樣的一個事件你有了多個處理. 分層目錄結構指標和資料成形 如果你處理資料,那?很可能你需要將它從多個表中提取出來.在大多數情況下,你使用JOIN命令合併 相關表中的資料,特別是在你訪問關係型數據庫的情況下.任何由JION命令形成的記錄集總是包含了 多餘的資訊.例如,如果你對一個作者的所有書籍感興趣的話,你可以合併Authors和Title Author表 (我在這裏指的是Biblio和PUBS資料庫).在返回的記錄集中,關於作者的資訊在每一行中無效地重復. 你合併的嵌套次數越多或越複雜,消除多餘資訊對於你來說就越重要,分層目錄結構指標允許你以基 於樹形的邏輯來組織你的記錄集.該過程也叫做資料成形,並且它可以以兩種方式來實現.你可以用 類似于SQL的成形語言,或者你可以通過使用Visual Studio 6.0的相應的高級工具.我將在後面提供 一個例子.現在我們來看看成形語言. 就某方面來說,成形語言顯得跟SQL語言類似. SHAPE {select au_ID, Author from authors} APPEND ( {select ISBN from [title author]} AS chapter RELATE au_id TO au_id) 一般說來,SHAPE命令定義記錄集,APPEND子句添加一個子記錄集到它當中去.換而言之,記錄集可以 作?一個域的其他任何資料類型使用.(見圖6).父記錄集和子記錄集是通過域與域間的關係實現連 接,該關係同樣需要一個名稱. 圖 6 APPEND 記錄集 作?資料成形的結果,父記錄集附加了新的一列.每行中的新的域都是指向定義在APPEND從句中所定 義的記錄集.子記錄集只列舉那些au_id值跟父記錄集中相同的域的是匹配的記錄.在前面的代碼中, 如果給出一個作者的ID,那?存在一個記錄集,在它當中有一個叫Chapter的附加的域,它的Value屬 性是指向一個子記錄集,該子記錄集中有來自於Title Autor表的所有所請求的域,在本例中, 是ISBN.圖7舉例說明了一些用於分層目錄結構記錄的定位的Visual Basic源代碼.注意我是怎樣 通過名稱來訪問Chapter域.?了得到實際的子記錄集,還需要另外一個步驟:調用Value屬性. SHAPE命令也可以嵌套.這意味著你能用其他的SHAPE命令作?APPEND的內部命令.跟SHAPE語法打交 道如同手工書寫SQL查詢一樣也是件煩人的事情.幸運的是,Visual Studio 6.0給你提供了高級的工 具它可以顯著地簡化SHAPE查詢地定義.我將簡要地說明這一點. APPEND不是唯一一個你可以附在SHAPE命令上的從句. 你還可以改用一個COMPUTE從句來代替.COMPUTE 能讓你對已有的行執行統計功能,或按一個或更多的域進行分組.其預定義的函數有SUM, AVG, MAX和 MIN.在最後的記錄集裏就給出了父行的這些操作的結果.而且,該記錄集也包含了一個引用域,它指向 由COMPUTE處理的原始行所在實際表.是不是覺得不太明白?讓我們來看看一個例子. 假設你有個客戶定單表.一天,你想知道每個姓是以A開頭的客戶的定單的總數. SHAPE {select custID, last name from orders where last name like 'A%''} COMPUTE (SUM(amount)) AS chapter BY custID 圖8說明了結果記錄集.你有用戶的ID,姓,和訂單的總數,除了客戶定單的列表引用外,其他的都是形 式非常簡單的. 圖 8 COMPUTE 記錄集 ?在較底的層次上(也就是說,沒有用專用工具的情況下)實現資料成形功能,你得指定你的提供者? MSDataShape. Dim cnn As New ADODB.Connection cnn.Provider = "MSDataShape" cnn.Open "Biblio" Visual Basic 6.0 資料環境設計器 Visual Basic 6.0的最引人注目的新特性之一就是Data Environment Designer資料環境設計器 (見圖9).它是個一般的,設計時環境,它能讓你視覺化地安排三種類型的資料工具:連接,命令和記 錄集.Data Environment也是個物件.你可以將它包括在你的Visual Basic工程中,並在你的代碼中 引用它.(見圖10). 圖 9 Data Environment Designer ?添加一個實例到工程中,只需要選擇Project|Add Data Environment.於是,你就可以象其他任何 物件那樣來處理它了.唯一的區別在於它是是個在整個工程範圍內都有效的物件,而不是專門針對一 個給定的表單的. 圖 10 Data Environment Object Model(資料環境物件模型) Data Environment物件模型是由三個集合組成:Commands, Connections和Recordsets,當然還要 加上一些通用的屬性如Object和Name.你可以把一個物件嵌入到你的工程組中,並用它來準備任何你 在運行時需要的資料連接和查詢.Data Environment模糊了SQL查詢語言和SHAPE語言的差別.你可以 簡單的定義命令,並可以圖形化地做到這一點.(見圖11).也就是說,應該由下面的環境來做這事情. 圖 11 創建查詢 這裏有向導,對話方塊和工具條按鈕幫助你快速的創建任何類型的記錄集.例如,在圖9中,你可以看到兩 種不同的連接,它們是跟一個Microsoft Access資料庫(通過針對ODBC的OLE提供者)和一個SQL Server 表連接.從設計者的立場來看,兩個記錄集的創建方式是完全相同的.嵌套命令物件的存在造成了這裏 的分層目錄結構的記錄集.你可以通過上下文功能表添加子命令,如圖12所示.定義一個新的連接如同遵 從圖13中的指令一樣簡單. 圖 12 添加一個子命令 圖 13 創建一個新連接 你可以用多種方式在Data Environment Designer環境下創建一個物件.例如,你可以設定從新的 ADODC控制項到MSFlexGrid的任何資料覺察控制項的DataSource屬性.第二,你可以利用它的物件模型 並直接訪問任何預定義的連接,命令和記錄集.你也能添加一些代碼,它對ADO物件和DataEnvironment 的初始化和終止作出回應.?做到這一點,只需要在Project View視窗中選擇DataEnvironment物件, 並切換到代碼視(見圖14) 圖 14 處理ADO事件 在Visual Basic 6.0中, Data Environment Designer跟DataView窗口相配合發揮作用,IDE工具允 許你查看任何資料源的內部結構同時也可以創建新的資料連接. 在不同的環境下編寫ADO 當用Visual Basic 6.0編寫ADO時,你不能忽視Hierarchical FlexGrid(HFlexGrid)控制項,見圖15所示. 圖 15 Hierchical FlexGrid 它顯然比原來版本的Visual Basic的FlexGrid控制項好得多.它得新特性如名稱暗示的那樣:內置對 分層目錄結構的記錄集的支援.圖16顯示了一個簡單的基於Visual Basic 6.0的程式,它用到了 HFlexGrid控制項並概述了我目前所涉及的所有的ADO的特性.在該例子中,我定義了一個 DataEnvironment物件並用它來從包含了一個作者的所有的書的Biblio中獲取一個記錄集. Data Environment鍵和HFlexGrid控制項間缺少的連接可在該片段中找到. 圖 16 演示程式 Private Sub cmdDataEnv_Click() Set hflex.DataSource = DataEnv Set hflex.DataMember = DataEnv.RecordsetName End Sub 該代碼自動定義了DataEnvironment物件,在早先我是將它定義來作?HFlexGrid控制項的資料源. HFlexGrid控制項也可以成功的用於顯示平面記錄集並且在功能上是跟原來版本的Visual Basic一樣的. 可以通過新的名?MsAdoDC.ocx的ActiveX控制項來使得ADO的功能可用.它看起來象早先的但目前 仍然被支援的Data控制項.ADODC被假定?在你喜歡上它後將取代Data控制項.如你可能猜到的那樣, ADODC具有Data控制項中所沒有的特性.它是基於OLE DB的並公開了ADO 2.0編程介面. 圖 17 ADODC控制項 在Visual Studio 6.0中,Visual InterDev是個主要的Web開發工具.它有兩個專門的特性: Data Environment物件(相同的東西在Visual Basic中也能被找到)和Recordset設計時控制項.該思想是 簡單的,添加Data Environment物件到工程中,定義你的資料連接,查詢和完成其他你所需要的任 何工作.當你完成後,你將Recordset設計時控制項插入到你的Active Server Pagers中,並從Data Environment集合--Recordsets, Commands, Connections中提取你所需要的資料物件(記錄集, 命令和連接). < script language="JavaScript" runat="server"> function InitRS() { thisPage.createDE(); var rsTemp = DE.Recordsets('authors'); rsAuthors.setRecordSource(rsTemp); rsAuthors.open(); } 先前的代碼段說明了一個JavaScript過程,它恢復一個記錄集並?在頁面中進一步使用它而打開它. 在C 下使用ADO,並且通常使用源於C 的高級物件模型,常常引起下面的問題即需要將方法返回 的Variant類型轉換成語言的本地類型.由於這個原因,ADO 2.0公開了附加的叫做IADORecordBinding 的介面,使得你將記錄集的特定類型綁定?C 類型.這可以通過如下步驟來完成: 定義一個從CADORecordBinding派生出來的類並在頭文件irsint.h裏聲明它.這個類必須有如下三個 方法: BindToRecordSet, AddNew和Update. 將盡可能多的所需要的資料成員添加到類中以映射記錄集的域.通過使用其中一個如下的預定義的宏 將每個記錄集的域跟它相應的資料成員綁定起來, ADO_VARIABLE_LENGTH_BINDING_ENTRY, ADO_FIXED_LENGTH_BINDING_ENTRY和ADO_NUMERIC_BINDING_ENTRY.所有這些對宏的調用必須由 下面的給包圍起來. BEGIN_ADO_BINDING END_ADO_BINDING 當你得到一個記錄集,調用BindToRecordset,將其指標傳給你的類. 現在,根據你的需要對記錄集進行處理.重要的是從現在開始你可以對你自己的資料成員而不是對 記錄集的源資料進行處理.每次你移動當前位置的時候,資料會被自動地提取出來並放在C 地類 實例變數中. 在Java語言中也有同樣的問題,在Visual J 6.0中是通過在Field中引入附加的方法來解決這一 問題. 在Visual J 6.0環境下,在Java語言中使用ADO進行資料訪問已變得簡單了.新的Visual J 所基 於的WFC包括了一些特殊的專門用於資料管理的類.結果是在Java語言中編寫一個資料庫應用程式變 得比以前容易多了. 讓我們來回顧一下Visual J 1.1的情況.你可以調用ADO 1.5物件模型,但是你必須通過COM來實現 這一點.由於Java/COM集成模型的因素,你需要在你的基於Java的程式和希望的COM伺服器之間有一 套介面類.以這種方式,Microsoft Java Visual Machine能挂接這些介面並將它們重定向到實際的服 務器上.你也需要一個象Java Type Library Wizard(Java類型庫向導, javatlb.exe 或 jcom.exe) 的工具來幫助你來生成所有的包裝類.最後一步是調用Visual J Database Wizard來完成工作. 使用Visual J 6.0和WFC是完全不同的情況.現在類庫公開了三種物件,分別叫做: Connection, Command和Recordset.它們的方法和屬性跟我在早些時候討論的ADO物件模型是一一對應的.ADO事件也 可以遵循典型的收聽者JDK模型來處理. 最重要的是,編程者的工作只是編寫Java代碼—不需要考慮工具,向導和中間類.下面是一個如何建立 一個連接並打開一個記錄集的例子. void openDataConnection() { m_con = new Connection(); m_rs = new Recordset(); m_con.setConnectionString( "Provider=MSDASQL.1;UID=sa; PWD=;DATABASE=pubs;DSN=SQLS;SERVER=(local);" ); m_con.setCursorLocation( AdoEnums.CursorLocation.CLIENT ); m_con.open(); m_rs.setActiveConnection( m_con ); m_rs.setSource( "select * from authors" ); m_rs.setCursorType( AdoEnums.CursorType.STATIC ); m_rs.setCursorLocation( AdoEnums.CursorLocation.CLIENT ); m_rs.setLockType( AdoEnums.LockType.OPTIMISTIC ); m_rs.open(); } Visual J 也?你提供了四個面向資料的元件: DataSource, DataBinder, DataNavigator和DataGrid. DataSource實施一個資料庫的連接,而DataBinder實現的功能多少象一組UI控制項的粘合劑.這些元件在當 前行的位置變化時會自動刷新.DataBinder是跟特定的DataSource相連.DataNavigator跟Visual Basic 的Data控制項很相似(即使是用戶介面也很類似),而DataGrid是一個典型的基於資料源的柵格. 這是一個概述,它是關於這些內容:基於Java語言的WFC類庫關於在使用ADO 2.0進行資料訪問的情況下的 相關內容.Visual J 也使用向導來使得用Java開發框架資料庫應用程式變得容易. Web端的ADO 去年當Internet Explorer 4.0發佈時,很少有編程者真正領會到資料綁定特性的重要性.該特性看起來 太棒了,但是它依賴於Internet Explorer 4.0並且缺乏適當的例子和應用程式.資料綁定是一項基於Web 的技術,它能讓你不離開當前頁面去訪問遠端的資料源.換而言之,資料綁定是資料覺察控制項的Web版.如果 你使用它,你能讓資料綁定HTML標簽.舉例來說吧,你可以將一個< TABLE> 連接到一個特定的資料源並且 可以讓行和列在記錄實際上進來的時候進行非同步的添加.一旦你建立一個綁定,你(和你的用戶)不再需 要做其他的事情. 資料綁定是通過一個叫做Data Source Object(DSO)的模組來實現的,它實際上是一個ActiveX控制項,它 起到的大致作用是一個介於資料庫和Web頁面的代理.Microsoft?Internet Explorer 4.0提供了兩個 DSO: Tabular Data Control (TDC) 和 Advanced Data Control (ADC).TDC只能處理基於文本的資料, 而ADC能連接到任意ODBC源.?有個初步的認識,你可以參考Rich Rollmann (MIND, July 1997)寫的文 章"Data Binding in Dynamic HTML".現在,ADC演變?RDS—它是Web端的UDA和ADO的一部分,它被認? 是專門用於Internet的. 其中一個RDS是一個名叫RDS.DataControl 的ActiveX控制項,你可以將它放到HTML頁面裏.通過使用資料 綁定技術,你可以在用戶端有效地管理記錄集.你可以對行進行定位,分類,刷新而不需要進一步跟服務 器聯繫.只有在刷新挂起的變化時你才要回到伺服器上.RDS在用戶端對資料進行緩存並極大地減少了 對往返行程的需要.下面的代碼行顯示了如何在HTML頁面中使用RDS來填寫一個表單. < object id="rds" classid="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"> < /object> < table "#rds"> < thead> < tr> < th> First Column< /th> < th> Second Column< /th> < /tr> < /thead> < td> < span "FieldName1"> < /span> < /td> < td> < span "FieldName2"> < /span> < /td> < /table> RDS資料工廠 並不是所有的RDS都在用戶端.當你通過VBScript或Jscript調用RDS ActiveX控制項的方法時,你實際 上最後調用的是RDS Data Factory Server (RDSServer.DataFactory物件),它是位於Web的伺服器 空間的.由於這個因素,資料綁定可以將你綁定到一個相容的瀏覽器上或一個啟動了RDS的伺服器上. RDS Data Factory通過ADO介面以訪問下面的資料源的方式來獲取請求並完成它們.(見圖18).它只是 完成查詢和更新的工作. 圖 18 RDS的體系結構 目前,RDS被定義?ADO的一部分並成?整個UDA體系結構的一個基本的元件.ADO 2.0加強了RDS方面的 功能. 對RDSServer.DataFactory物件進行了改進以支援一層自定義的代碼,該代碼的目的是添加合 法性驗證的能力和訪問許可權控制.這個被叫做Handler的新模組可以在執行時對命令字串和連接參 數進行修改.一個Handler可以被一個初始化文件驅動並且通過添加如下的句子來調用: Handler=progID,arg1,arg2,…, argn 在記錄集連接字串中,需要用ProID來標識Handler,它是執行IdataFactoryHandler介面的COM伺服器. Microsoft提供了缺省的名?MSDFMAP.Handler的Handler,它是在msdfmap.ini文件中規定的.如果你 自己想的話,你可以編寫自己的Handler(處理).下面是一段對msdfmap.ini文件的摘錄,你可以在你的 Windows目錄下找到它: [connect AuthorDatabase] Access=ReadOnly Connect="DSN=MyLibraryInfo;UID=MyUserID;PWD=MyPassword" [userlist AuthorDatabase] Administrator=ReadWrite [sql AuthorById] Sql="SELECT * FROM Authors WHERE au_id = ?" 這意味著任何對AuthorDatabase的連接必須總是有唯讀許可權並且總是要輸入特定的字串.名? Administrator的用戶有讀/寫許可權,並且該設置部分覆蓋了先前的一個.所有其他的用戶仍然只有 唯讀許可權.sql部分指向一個名?AuthorById的過程.每次它被調用時,它必須被特定的聲明所取代, 並且?符號必須被第一個過程參數所取代. rds.Handler = "MSDFMAP.Handler" rds.Server = "…" rds.Connect = "Data Source=AuthorDatabase" rds.SQL = "AuthorById(16100)" 該代碼向你說明了你如何在VBScript中通過Handler來調用RDS.RDS控制項也可以無縫地運用到桌面應 用程式中.它最初的目標是基於Web,通過RDS和Dynamic HTML,舉例說,來形成一個真正引人注意的套 件.特別是你可以編寫自主式的HTML元件(scriptlet)來在< TABLE> 元素中給出一個記錄集.關於這方 面的例子見MIND的1998年10的Cutting Edge欄目. 多維的ADO ADO 2.0也擴展了OLE DB和關於On-Line Analytical Processing (OLAP)的Universal Data Access 的原則.它是通過引入MultiDimensional ADO (ADO MD)來做到這一點的. MultiDimensional ADO (ADO MD)是一套COM物件,使用它可以使多維的資料管理變得更容易. ADO MD並不局限於ADO物件模型並且包含了專門針對多維資料的物件,如cube.在ADO MD的外殼下面 運行的是一個OLE DB提供者,它是跟符合OLAP規範的OLE DB相容的.ADO和ADO MD是相關的但不是相 同的.兩者都對記錄集起作用,即使這些記錄集對於ADO是扁平的,或是雙向的陣列,或者對於ADO MD 來說是n維的物件,其結果都是一樣的. ADO MD的對應著記錄集的相應部分叫做cellset.它是從源於關聯式表的資料中提取出來的.如果你 是的確需要的話,你可以在同一個工程中同時使用ADO和ADO MD.要參考例子,請看MSDN文檔. 小結 這篇文章並沒有試圖提供所有ADO物件的對所有方法和屬性的詳盡的描述.就這方面有相應的文檔 和不錯的書.我在這裏的初衷是試圖向你介紹一些ADO在企業和分散式系統方面的新特性.ADO 2.0 超出了RDO
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-07-03 18:55:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!