ODBC實(shí)現(xiàn)Domino和關(guān)系數(shù)據(jù)庫的互操作
一、Lotus Domino與關(guān)系數(shù)據(jù)庫的互操作
在Lotus Domino R5中提供了三個Lotus Notes擴(kuò)展類:ODBCConnection(ODBC連接)、ODBCQuery(ODBC查詢)以及ODBCResultSet(ODBC結(jié)果集)。應(yīng)用這三個類并輔以Lotus Script語言就能實(shí)現(xiàn)與關(guān)系數(shù)據(jù)庫的互操作問題。 具體解決方法如下: 第1步:在控制面板→32位ODBC數(shù)據(jù)源中建立用戶數(shù)據(jù)源Test; 第2步:在Domino R5中新建一個數(shù)據(jù)庫Try,并建立一個空白表單Con-nection,此表單沒有任何內(nèi)容,然后在表單上創(chuàng)建一個“操作”,起名為“Read”; 第3步:在“Read”操作的編程窗口中選擇編程語言為Lotus Script; 第4步:在編程窗口的對象窗口中點(diǎn)擊“Option”事件,并寫入如下腳本: Uselsx "lsxodbc" // 使用Lotus Script 擴(kuò)展ODBC類 第5步:選中“Declare”事件,在其中寫入: Dim session As NotesSession Dim db As NotesDataBase Dim doc As NotesDocument Dim qry As ODBCQuery Dim result As ODBCResultSet Dim con As ODBCConnection 第6步:選中“Click”事件,在其中寫入: Sub Click(Source As Button) ′ Set New Value Set session=New NotesSession Set con=New ODBCConnection Set qry=New ODBCQuery Set result=New ODBCResultSet ′ Get Current Database Set db=session.CurrentDataBase Set doc=New NotesDocument(db) doc.form="connection" Call con.Disconnect() If con.ConnectTo("test") Then Set qry.connection=con qry.SQL="SELECT FROM Table1" Set result.Query=qry Call result.Execute() columns=result.Columns Do Call result.NextRow() For i=1 To result.Numcolumns field=result.FieldName(i) value=result.GetValue(field) If Isdate(value) Then If value=Datevalue("0:00:00") Then value=" " Else value=Format(value,"mm-dd-yyyy") End If End If Set item=doc.AppendItemValue(field,val-ue) Next Call doc.save(True,True) Set db=session.CurrentDataBase Set doc=New NotesDocument(db) doc.form="test" Loop Until result.IsEndOfData Call con.Disconnect() Else Messagebox("Could not connect to server") End If End Sub 最后,保存表單并運(yùn)行,用鼠標(biāo)點(diǎn)擊Read操作后,關(guān)系數(shù)據(jù)庫中的內(nèi)容就被取到Notes的文檔型數(shù)據(jù)庫中了。 二、程序存在的問題及解決 但是使用上面的代碼在進(jìn)行實(shí)際數(shù)據(jù)庫內(nèi)容轉(zhuǎn)換的時候,我們發(fā)現(xiàn)Notes 通過ODBC數(shù)據(jù)源連接關(guān)系數(shù)據(jù)庫時,無法識別中文字段名。如果關(guān)系數(shù)據(jù)庫的字段是中文名字,那么ODBCResultSet將為空,解決的辦法是將關(guān)系數(shù)據(jù)庫中的所有字段都改為英文名字。 在實(shí)際數(shù)據(jù)庫的轉(zhuǎn)換過程中同時發(fā)現(xiàn)的問題還有:該程序執(zhí)行完一次后不能把關(guān)系型數(shù)據(jù)庫中的內(nèi)容全部取出來。通過調(diào)試Lotus Script腳本并多次單步跟蹤腳本的執(zhí)行情況,發(fā)現(xiàn)每次都是執(zhí)行到同一條數(shù)據(jù)庫記錄時,ODBCRe-sultSet就認(rèn)為數(shù)據(jù)集已經(jīng)到頭了,下面的記錄就都丟了。于是使用關(guān)系數(shù)據(jù)庫軟件打開數(shù)據(jù)庫,并將其中的字段減少若干條后,就可以一次讀取出全部記錄。至于需要減少多少個字段才能一次讀取出全部記錄跟原先的關(guān)系型數(shù)據(jù)庫的結(jié)構(gòu)有關(guān),需要具體情況具體實(shí)驗(yàn)。 三、Lotus Domino中的日期處理 上面程序中有如下一段程序: If Isdate(value) Then If value=Datevalue("0:00:00") Then value=" " Else value=Format(value,"mm-dd-yyyy") End If Set item=doc.AppendItemValue(field,value) End if 這一段代碼的作用是:判斷從關(guān)系庫中讀取出來的字段是否為日期型字段,如果是,那么判斷此日期型字段的值,看它是否為空,如果為空則在寫入Notes庫的時候做處理,保證寫入的是空日期類型,如果此字段的值不為空則直接寫入Notes庫;如果此字段不是日期型字段,則不做任何處理。 若是不做上述處理,那么通過ODBCResultSet類取出的日期型字段的值如果為空,則寫入Notes庫的時候不知什么原因會寫入“1899年12月30日”這個日期。 在代碼中,使用到了一個DateValue(string)函數(shù),此函數(shù)的功能是將字符串參數(shù)轉(zhuǎn)換成日期數(shù)據(jù)類型,如果字符串所表示的內(nèi)容找不到合法的日期數(shù)據(jù)與之對應(yīng),那么此函數(shù)將保留字符串的值不變,而僅僅把其數(shù)據(jù)類型轉(zhuǎn)換成日期型,即實(shí)現(xiàn)了強(qiáng)制類型轉(zhuǎn)換函數(shù)的功能。而代碼中的“0:00:00”字符串是個特殊字符串,在通過ODBC數(shù)據(jù)源讀取關(guān)系數(shù)據(jù)庫的記錄時,如果關(guān)系庫中的日期型字段值為空,那么取出的值就是“0:00:00”形式的日期。使用DateValue(“0:00:00”)語句就可以判斷取出的日期型變量的值是否為空,如果為空則將變量Value的值賦成空字符串,然后再寫入Notes庫中,就可避免出現(xiàn)“1899年12月30日”這個日子了。 四、NotesItem NotesItem是可以代表所有表單元素的對象,簡單地說就是所有可放置在表單上的元素,在Lotus Script程序中都可以用NotesItem對象表示并對其進(jìn)行操作。上面代碼中的doc.AppendItemValue(fieldname,value)函數(shù)的作用就是根據(jù)Value的值為表單追加域(也就是關(guān)系庫中的字段)。 其實(shí)細(xì)心的讀者一定已經(jīng)發(fā)現(xiàn)了,在上面關(guān)于空日期的處理代碼中,為什么要先把Value的值賦成空,然后再寫入庫中呢?為什么不可以直接往庫里寫值呢?問題的關(guān)鍵就在NotesItem上。 NotesItem有很多屬性,其中最重要的兩個是Name和Text屬性。Name屬性存放表單元素的名稱(即fieldname),而Text屬性存放表單元素的值(value)。在程序執(zhí)行到doc. AppendItemValue(fieldname,value)函數(shù)的時候,Notes將域名(fieldname)和相對應(yīng)的值(value)寫到NotesItem對象中。執(zhí)行Call doc.Save()函數(shù)之后,所有內(nèi)存中的NotesItem對象被存入相關(guān)聯(lián)的表單中。 在研究如何處理空日期的過程中,最初的想法是直接將空字符串寫入NotesItem中,但是在查看幫助并單步跟蹤腳本的執(zhí)行后發(fā)現(xiàn)上述方法行不通。原因在于NotesItem的Text屬性是只讀的,根本無法為其賦值,同時也沒有相應(yīng)的賦值函數(shù),顯然函數(shù)doc.AppendItemValue(fieldname,value)是專門給Text屬性賦值的函數(shù)。 五、Notes中視圖與表單的關(guān)聯(lián) 在開發(fā)過程中,由于一次錯誤,我們意外地發(fā)現(xiàn)了Notes中視圖與表單的關(guān)聯(lián)技巧。Notes為每個表單都設(shè)置了名稱與別名兩個屬性,這兩個名字都能標(biāo)識表單。在開發(fā)過程中,我們所開發(fā)的庫有兩個表單,分別命名為Form1和Form2,其各自的別名由于疏忽都設(shè)成了Docu-ment,而每個表單都有一個視圖與之對應(yīng)。在設(shè)計Form2的視圖時,雖然指定視圖中的列都與Form2中的域相關(guān)聯(lián),但是在運(yùn)行的時候從視圖中雙擊某條文檔欲對其進(jìn)行編輯時,切換到的表單卻是Form1的,多方查找均不能解決這個問題,于是抱著試試看的心理改變了表單的別名,分別為Document1和Docu-ment2,結(jié)果問題解決。但是又出現(xiàn)了Form1的視圖無法切換到表單的情況,于是又將Form1的別名改回Document,兩個視圖均能正確切換到自己的表單上了。 由此發(fā)現(xiàn),Notes在建立視圖與表單的關(guān)聯(lián)的時候,首先看表單是否具有別名,如果有,則用別名進(jìn)行關(guān)聯(lián),一旦對表單的別名進(jìn)行了改變就得重新設(shè)計視圖,如果不想重新做視圖就不能改變表單的別名。當(dāng)然同時也可以應(yīng)用這一技巧實(shí)現(xiàn)從視圖中切換到不同表單的功能。如果表單沒有別名,則使用名稱進(jìn)行關(guān)聯(lián)。 |
|