全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1659
推到 Plurk!
推到 Facebook!

MDB資料連結另一MDB資料表問題

答題得分者是:aftcast
g9221712
高階會員


發表:145
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-09-12 02:13:09 IP:220.134.xxx.xxx 訂閱

各位前輩:

我欲撰寫一個簡易在MDB中產生資料表連結的函數Link_MDB,連結是可以連結成功,不過卻發現會產生一個意外狀況
就是連結MDB的.ldb (MicroSoft Office Access 紀錄鎖定資訊檔),不會自動消失就算我,不知道我函數中哪邊有出錯。
下列為我的函數Source Code 提供給大家參考,MDB真是個讓人又愛又恨得資料庫格式。

unit UNT_MS_Access_MDB;

interface
uses
SysUtils, Windows, ComObj, ActiveX, ADOX_TLB, ADODB, Forms;

function Link_MDB(Source_MDB_Name: string; Target_MDB_Name: string; TableName: string; DB_PASSWORD: string = ''): boolean;

implementation


function Link_MDB(Source_MDB_Name: string; Target_MDB_Name: string; TableName: string; DB_PASSWORD: string): boolean;
var
StrDataPath: string;
Cnt_S: TADOConnection;
catDB: Catalog;
TableIndex: Integer;
tblNew: Table;
IsMDBTable: Boolean;

begin
StrDataPath := ExtractFilePath(Application.ExeName) '\';

Cnt_S := TADOConnection.Create(nil);
Cnt_S.ConnectionString :=
'Provider=Microsoft.Jet.OLEDB.4.0;'
'Password="";'
'User ID=Admin;'
'Data Source=' Target_MDB_Name ';'
'Mode=Share Deny None;'
'Extended Properties="";'
'Jet OLEDB:System database="";'
'Jet OLEDB:Registry Path="";'
'Jet OLEDB:Database Password="' DB_PASSWORD '";'
'Jet OLEDB:Engine Type=5;'
'Jet OLEDB:Database Locking Mode=1;'
'Jet OLEDB:Global Partial Bulk Ops=2;'
'Jet OLEDB:Global Bulk Transactions=1;'
'Jet OLEDB:New Database Password="";'
'Jet OLEDB:Create System Database=False;'
'Jet OLEDB:Encrypt Database=False;'
'Jet OLEDB:Don''t Copy Locale on Compact=False;'
'Jet OLEDB:Compact Without Replica Repair=False;'
'Jet OLEDB:SFP=False';
Cnt_S.LoginPrompt := false;
Cnt_S.open;

// 利用 ADOX 組物件來動態產生 Access Table
// 須先 import type library -> Microsoft Jet and Replication Objects 2.5 Library (Version 2.5)
catDB := CoCatalog.Create;
catDB.Set_ActiveConnection(Cnt_S.ConnectionObject);

// 檢查檔案是否存在
IsMDBTable := False;
for TableIndex := 0 to catDB.Tables.Count - 1 do
begin
if (catDB.Tables[TableIndex].Name = TableName) then
begin
IsMDBTable := True;
Exit;
end;
end;

if IsMDBTable = True then
begin
catdb.Tables.Delete(TableName);
end;

tblNew := nil;
tblNew := CoTable.Create;
tblNew.Name := TableName;
tblNew.ParentCatalog := catDB;

tblNew.Properties['Jet OLEDB:Create Link'].Value := True;
tblNew.Properties['Jet OLEDB:Link Datasource'].Value := Source_MDB_Name;
tblNew.Properties['Jet OLEDB:Link Provider String'].Value := 'MS Access;PWD=' DB_PASSWORD ';';
tblNew.Properties['Jet OLEDB:Remote Table Name'].Value := TableName;
catDB.Tables.Append(tblNew);

tblNew.ParentCatalog := nil;
tblNew._Release;
tblNew := nil;
catDB := nil;
catDB._Release;

Cnt_S.Connected := false;
Cnt_S.Close;
Cnt_S.Destroy;
Cnt_S := nil;


result := true;
end;


end.

------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2006-09-12 17:23:04 IP:61.229.xxx.xxx 未訂閱
g9221712 你好,你程式愈寫愈進階呢! 你的這個問題我想是極少人知道的。不過…剛好我之前自己也有遇到過,花了不少的時間自己想辦法測式和追踪,終於有了解答…雖然只能少少的幾行,但會搞死人,這就是所謂的江湖一點訣吧! 不過,我不敢完全保証你用了也會有效,因為是類似並非完全相同。還有,我是bcb的程式,而bcb與delphi在com元件的實作上是相去最多的地方,所以還要靠一下下你自己把我的概念換成delphi,因為我沒裝delphi的環境,也沒法幫你測了。若有測出來,或是沒有,都請post上來了解一下吧!


===================引 用 文 章===================

各位前輩:

我欲撰寫一個簡易在MDB中產生資料表連結的函數Link_MDB,連結是可以連結成功,不過卻發現會產生一個意外狀況
就是連結MDB的.ldb (MicroSoft Office Access 紀錄鎖定資訊檔),不會自動消失就算我,不知道我函數中哪邊有出錯。
下列為我的函數Source Code 提供給大家參考,MDB真是個讓人又愛又恨得資料庫格式。

我發現你說 「// 須先 import type library -> Microsoft Jet and Replication Objects 2.5 Library (Version 2.5)」這好像有錯,應該是「Microsoft ADO Ext. 2.x for DDL and Security」才對,那裡面才有Table, Catalog等元件。

tblNew.ParentCatalog := nil;

//這裡要加入幾行程式,我要放入的是對應我bcb的程式碼,請你自己改成delphi的

Variant vv;
vv = cat->get_ActiveConnection();
vv.OleFunction("Close");

//就我所知,delphi裡應該用的是OleVariant,簡單講,原理就是使用cat->get_ActiveConnection();傳回一個Variant物件,然後強硬使用它Close的方法!如果成功了,你下面的一堆nil,false,close,destroy應該都可以省了,但_Release 要留著。你也許會想…可是我下面有用 Cnt_S.Connected := false; Cnt_S.Close;但意義有些不一樣。先試試看吧!


tblNew._Release;
tblNew := nil;
catDB := nil;
catDB._Release;

Cnt_S.Connected := false;
Cnt_S.Close;
Cnt_S.Destroy;
Cnt_S := nil;


result := true;
end;


end.

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
g9221712
高階會員


發表:145
回覆:344
積分:162
註冊:2006-07-06

發送簡訊給我
#3 引用回覆 回覆 發表時間:2006-09-13 04:13:04 IP:220.134.xxx.xxx 訂閱

aftcast前輩:

感謝您的回應,其實我也沒多大長進,只是找了網路上找程式碼,想到達成自己的目標而已,

我試了您所說得方法,不過他會出現Microsoft Jet 資料庫引擎無法找對輸入的查詢或資料表

vv := catdb.Get_ActiveConnection();
vv.OleFunction('Close');

我加上的語法如上,不過錯誤在哪其實我也不知道,JET資料庫底層其實我也沒有了解很透徹,
只是我知道MDB有個特性,使用連結的方式來操作資料表,可以減少MDB毀損的機會,因為自己
死過太多mdb的檔案了都怕了。

我想了一個很不爭氣的作法,因為ldb檔案其實會自己產生的,我想若我無法解決的話,直接下達
刪除檔案的方式將其刪除,不過我知道這種作法治標不治本,但是有時候想想,我只是要寫個資料庫
程式就要了解好多相關技術,就好像要吃一晚牛肉麵,就要學會殺牛一樣,真是疲憊。

不過有aftcast前輩的回應,雖然有時無力只想在Ktop找到不求甚解的但解決程式碼,
但是我要達到您的境界,我只好學習從臨摹開始,我會繼續努力的!

------
「人們所以覺得寂寞,是因為他們會築牆,卻不會搭橋。」
程式寫的越久,卻發現自己越來越不會寫程式!
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2006-09-13 11:15:31 IP:61.229.xxx.xxx 未訂閱

不要灰心。你試著想說用刪的…我也曾想過,但行不通,因為在同一個程序裡你就是無法刪它。除非你離開程式後,再跑另外的程式來砍!
我也是試了好幾回,我覺得應該是可以成功的,只是我手邊沒有delphi。問題是型別的問題嗎? 事實上我用了三種方式試過都可以成功,你要不要試看看別的二種? 另外,delphi中你是用OleVariant嗎? 還有,compile時有錯嗎? 還是沒錯,直到run time 時才出錯?
//另一種
Variant v;
cat->get_ActiveConnection(v);
v.OleFunction("Close");

//又另外一種
Variant *v = reinterpret_cast(&cat->get_ActiveConnection());
// 上面的 reinterpret_cast 在cpp中是指強硬轉型成Variant *v , * 是指標,在delphi應該是 ^
v->OleFunction("Close");

整個問題是你要把它轉型成功,通常只要compile有過,應該就沒問題!

加油!

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#5 引用回覆 回覆 發表時間:2006-09-13 11:17:14 IP:61.229.xxx.xxx 未訂閱
在delphi 是不是有 is 這個指令做轉型? 不過不知到能不能超強轉…
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
系統時間:2024-07-03 5:32:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!