利用ODBC實現Domino和關系數據庫的互操作
2024-07-21 02:09:27
供稿:網友
中國最大的web開發資源網站及技術社區,
利用odbc實現domino和關系數據庫的互操作
lotus domino是當今辦公自動化系統的主流開發平臺之一,domino自帶一個非關系型數據庫——文檔型數據庫,而目前大部分企業的信息都儲存在諸如sql server等關系型數據庫中,因此,在開發辦公自動化系統過程中勢必要涉及domino和關系數據庫的數據交換問題。
一、lotus domino與關系數據庫的互操作
在lotus domino r5中提供了三個lotus notes擴展類:odbcconnection(odbc連接)、odbcquery(odbc查詢)以及odbcresultset(odbc結果集)。應用這三個類并輔以lotus script語言就能實現與關系數據庫的互操作問題。
具體解決方法如下:
第1步:在控制面板→32位odbc數據源中建立用戶數據源test;
第2步:在domino r5中新建一個數據庫try,并建立一個空白表單con-nection,此表單沒有任何內容,然后在表單上創建一個“操作”,起名為“read”;
第3步:在“read”操作的編程窗口中選擇編程語言為lotus script;
第4步:在編程窗口的對象窗口中點擊“option”事件,并寫入如下腳本:
uselsx "lsxodbc" // 使用lotus script 擴展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
最后,保存表單并運行,用鼠標點擊read操作后,關系數據庫中的內容就被取到notes的文檔型數據庫中了。
二、程序存在的問題及解決
但是使用上面的代碼在進行實際數據庫內容轉換的時候,我們發現notes 通過odbc數據源連接關系數據庫時,無法識別中文字段名。如果關系數據庫的字段是中文名字,那么odbcresultset將為空,解決的辦法是將關系數據庫中的所有字段都改為英文名字。
在實際數據庫的轉換過程中同時發現的問題還有:該程序執行完一次后不能把關系型數據庫中的內容全部取出來。通過調試lotus script腳本并多次單步跟蹤腳本的執行情況,發現每次都是執行到同一條數據庫記錄時,odbcre-sultset就認為數據集已經到頭了,下面的記錄就都丟了。于是使用關系數據庫軟件打開數據庫,并將其中的字段減少若干條后,就可以一次讀取出全部記錄。至于需要減少多少個字段才能一次讀取出全部記錄跟原先的關系型數據庫的結構有關,需要具體情況具體實驗。
三、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
這一段代碼的作用是:判斷從關系庫中讀取出來的字段是否為日期型字段,如果是,那么判斷此日期型字段的值,看它是否為空,如果為空則在寫入notes庫的時候做處理,保證寫入的是空日期類型,如果此字段的值不為空則直接寫入notes庫;如果此字段不是日期型字段,則不做任何處理。
若是不做上述處理,那么通過odbcresultset類取出的日期型字段的值如果為空,則寫入notes庫的時候不知什么原因會寫入“1899年12月30日”這個日期。
在代碼中,使用到了一個datevalue(string)函數,此函數的功能是將字符串參數轉換成日期數據類型,如果字符串所表示的內容找不到合法的日期數據與之對應,那么此函數將保留字符串的值不變,而僅僅把其數據類型轉換成日期型,即實現了強制類型轉換函數的功能。而代碼中的“0:00:00”字符串是個特殊字符串,在通過odbc數據源讀取關系數據庫的記錄時,如果關系庫中的日期型字段值為空,那么取出的值就是“0:00:00”形式的日期。使用datevalue(“0:00:00”)語句就可以判斷取出的日期型變量的值是否為空,如果為空則將變量value的值賦成空字符串,然后再寫入notes庫中,就可避免出現“1899年12月30日”這個日子了。
四、notesitem
notesitem是可以代表所有表單元素的對象,簡單地說就是所有可放置在表單上的元素,在lotus script程序中都可以用notesitem對象表示并對其進行操作。上面代碼中的doc.appenditemvalue(fieldname,value)函數的作用就是根據value的值為表單追加域(也就是關系庫中的字段)。
其實細心的讀者一定已經發現了,在上面關于空日期的處理代碼中,為什么要先把value的值賦成空,然后再寫入庫中呢?為什么不可以直接往庫里寫值呢?問題的關鍵就在notesitem上。
notesitem有很多屬性,其中最重要的兩個是name和text屬性。name屬性存放表單元素的名稱(即fieldname),而text屬性存放表單元素的值(value)。在程序執行到doc. appenditemvalue(fieldname,value)函數的時候,notes將域名(fieldname)和相對應的值(value)寫到notesitem對象中。執行call doc.save()函數之后,所有內存中的notesitem對象被存入相關聯的表單中。
在研究如何處理空日期的過程中,最初的想法是直接將空字符串寫入notesitem中,但是在查看幫助并單步跟蹤腳本的執行后發現上述方法行不通。原因在于notesitem的text屬性是只讀的,根本無法為其賦值,同時也沒有相應的賦值函數,顯然函數doc.appenditemvalue(fieldname,value)是專門給text屬性賦值的函數。
五、notes中視圖與表單的關聯
在開發過程中,由于一次錯誤,我們意外地發現了notes中視圖與表單的關聯技巧。notes為每個表單都設置了名稱與別名兩個屬性,這兩個名字都能標識表單。在開發過程中,我們所開發的庫有兩個表單,分別命名為form1和form2,其各自的別名由于疏忽都設成了docu-ment,而每個表單都有一個視圖與之對應。在設計form2的視圖時,雖然指定視圖中的列都與form2中的域相關聯,但是在運行的時候從視圖中雙擊某條文檔欲對其進行編輯時,切換到的表單卻是form1的,多方查找均不能解決這個問題,于是抱著試試看的心理改變了表單的別名,分別為document1和docu-ment2,結果問題解決。但是又出現了form1的視圖無法切換到表單的情況,于是又將form1的別名改回document,兩個視圖均能正確切換到自己的表單上了。
由此發現,notes在建立視圖與表單的關聯的時候,首先看表單是否具有別名,如果有,則用別名進行關聯,一旦對表單的別名進行了改變就得重新設計視圖,如果不想重新做視圖就不能改變表單的別名。當然同時也可以應用這一技巧實現從視圖中切換到不同表單的功能。如果表單沒有別名,則使用名稱進行關聯。