ODBC實(shí)現(xiàn)Domino和關(guān)系數(shù)據(jù)庫的互操作
一,、Lotus Domino與關(guān)系數(shù)據(jù)庫的互操作
在Lotus Domino R5中提供了三個(gè)Lotus Notes擴(kuò)展類:ODBCConnection(ODBC連接)、ODBCQuery(ODBC查詢)以及ODBCResultSet(ODBC結(jié)果集),。應(yīng)用這三個(gè)類并輔以Lotus Script語言就能實(shí)現(xiàn)與關(guān)系數(shù)據(jù)庫的互操作問題,。 具體解決方法如下: 第1步:在控制面板→32位ODBC數(shù)據(jù)源中建立用戶數(shù)據(jù)源Test; 第2步:在Domino R5中新建一個(gè)數(shù)據(jù)庫Try,,并建立一個(gè)空白表單Con-nection,,此表單沒有任何內(nèi)容,然后在表單上創(chuàng)建一個(gè)“操作”,,起名為“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)換的時(shí)候,,我們發(fā)現(xiàn)Notes 通過ODBC數(shù)據(jù)源連接關(guān)系數(shù)據(jù)庫時(shí),,無法識(shí)別中文字段名。如果關(guān)系數(shù)據(jù)庫的字段是中文名字,,那么ODBCResultSet將為空,,解決的辦法是將關(guān)系數(shù)據(jù)庫中的所有字段都改為英文名字。 在實(shí)際數(shù)據(jù)庫的轉(zhuǎn)換過程中同時(shí)發(fā)現(xiàn)的問題還有:該程序執(zhí)行完一次后不能把關(guān)系型數(shù)據(jù)庫中的內(nèi)容全部取出來,。通過調(diào)試Lotus Script腳本并多次單步跟蹤腳本的執(zhí)行情況,,發(fā)現(xiàn)每次都是執(zhí)行到同一條數(shù)據(jù)庫記錄時(shí),ODBCRe-sultSet就認(rèn)為數(shù)據(jù)集已經(jīng)到頭了,,下面的記錄就都丟了,。于是使用關(guān)系數(shù)據(jù)庫軟件打開數(shù)據(jù)庫,并將其中的字段減少若干條后,,就可以一次讀取出全部記錄,。至于需要減少多少個(gè)字段才能一次讀取出全部記錄跟原先的關(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庫的時(shí)候做處理,保證寫入的是空日期類型,,如果此字段的值不為空則直接寫入Notes庫,;如果此字段不是日期型字段,則不做任何處理,。 若是不做上述處理,,那么通過ODBCResultSet類取出的日期型字段的值如果為空,則寫入Notes庫的時(shí)候不知什么原因會(huì)寫入“1899年12月30日”這個(gè)日期,。 在代碼中,,使用到了一個(gè)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”字符串是個(gè)特殊字符串,在通過ODBC數(shù)據(jù)源讀取關(guān)系數(shù)據(jù)庫的記錄時(shí),,如果關(guān)系庫中的日期型字段值為空,,那么取出的值就是“0:00:00”形式的日期。使用DateValue(“0:00:00”)語句就可以判斷取出的日期型變量的值是否為空,,如果為空則將變量Value的值賦成空字符串,,然后再寫入Notes庫中,就可避免出現(xiàn)“1899年12月30日”這個(gè)日子了,。 四,、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有很多屬性,,其中最重要的兩個(gè)是Name和Text屬性,。Name屬性存放表單元素的名稱(即fieldname),而Text屬性存放表單元素的值(value),。在程序執(zhí)行到doc. AppendItemValue(fieldname,,value)函數(shù)的時(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屬性是只讀的,,根本無法為其賦值,,同時(shí)也沒有相應(yīng)的賦值函數(shù),顯然函數(shù)doc.AppendItemValue(fieldname,,value)是專門給Text屬性賦值的函數(shù),。 五、Notes中視圖與表單的關(guān)聯(lián) 在開發(fā)過程中,,由于一次錯(cuò)誤,,我們意外地發(fā)現(xiàn)了Notes中視圖與表單的關(guān)聯(lián)技巧。Notes為每個(gè)表單都設(shè)置了名稱與別名兩個(gè)屬性,,這兩個(gè)名字都能標(biāo)識(shí)表單。在開發(fā)過程中,,我們所開發(fā)的庫有兩個(gè)表單,,分別命名為Form1和Form2,其各自的別名由于疏忽都設(shè)成了Docu-ment,,而每個(gè)表單都有一個(gè)視圖與之對應(yīng),。在設(shè)計(jì)Form2的視圖時(shí),雖然指定視圖中的列都與Form2中的域相關(guān)聯(lián),,但是在運(yùn)行的時(shí)候從視圖中雙擊某條文檔欲對其進(jìn)行編輯時(shí),,切換到的表單卻是Form1的,多方查找均不能解決這個(gè)問題,,于是抱著試試看的心理改變了表單的別名,,分別為Document1和Docu-ment2,結(jié)果問題解決,。但是又出現(xiàn)了Form1的視圖無法切換到表單的情況,,于是又將Form1的別名改回Document,,兩個(gè)視圖均能正確切換到自己的表單上了。 由此發(fā)現(xiàn),,Notes在建立視圖與表單的關(guān)聯(lián)的時(shí)候,,首先看表單是否具有別名,如果有,,則用別名進(jìn)行關(guān)聯(lián),,一旦對表單的別名進(jìn)行了改變就得重新設(shè)計(jì)視圖,如果不想重新做視圖就不能改變表單的別名,。當(dāng)然同時(shí)也可以應(yīng)用這一技巧實(shí)現(xiàn)從視圖中切換到不同表單的功能,。如果表單沒有別名,則使用名稱進(jìn)行關(guān)聯(lián),。 |
|