2017-05-22 167 views
2

爲了替代我的previous question這是令人困惑和制定不良,這裏是「真正」的問題。使用Delphi和Firedac設置sqlite數據庫的相對路徑

我想知道如何使用Firedac在運行時設置位於應用程序文件夾子文件夾中的sqlite數據庫的相對路徑。

由於Jerry Dodge說:

任何應用程序不應該在同一個目錄依靠可寫數據反正。另外,即使你做了,也應該確保你的所有路徑至少與應用程序相關。

此刻,我記住的應用程序是可移植的,我希望數據庫文件存儲在主exe文件夾的子文件夾中。

在我的主要形式的Form.Create事件,可以使用第一

path := ExtractFilePath(Application.ExeName); 

而且在那麼對於FDConnection:

with FDConnection1 do begin 
    Close; 
    with Params do begin 
    Clear; 
    Add('DriverID=SQLite'); 
    Add('Database='+path+'Data\sqlite.db'); 
    end; 
    Open; 
end; 

我不斷收到一個錯誤說「無法打開數據庫文件」。

我不想在FiredDac連接編輯器中設置數據庫文件的路徑,因爲那樣它就是絕對的並且綁定到我的機器上,對嗎?

如何將此路徑設置爲數據庫文件,以便在任何配置下工作,無論用戶放置應用程序文件夾?

謝謝大家提前

數學

+0

確保你有'FDConnection1.DriverName:='SQLite'設置。即使您的數據庫文件不在Win32 \ debug \ Data文件夾中,也應該在調用FDConnection1.Open時創建它,這樣您將遇到另一個問題 - 如果您的用戶刪除了db文件並且打開​​了一個新的空白一? –

+0

謝謝邁克爾抽空回答。是的,驅動程序已設置並且數據庫文件位於指定的文件夾中。抓住我的頭在這一個。 – Mathmathou

+0

如果您重命名文件會發生什麼?是否創建了一個新的?如果是這樣,您嘗試打開的那個可能會損壞,或由於某種原因無法讀取FireDAC。如果沒有,則應用程序可能會遇到一些麻煩,無法寫入該路徑(該子文件夾必須存在,不會被創建)。 – Victoria

回答

0

介紹

恕我直言

數據基本路徑和服務器名稱不應該在應用程序中進行硬編碼。

爲什麼?

  1. 當你在一個項目上工作時,你需要在數據庫連接,設置數據集,查詢等方面做很多事情。這些工作是在工作數據庫上完成的。然後,服務器名稱和數據庫路徑與真實數據庫的路徑不同。
  2. 您應該可以輕鬆設置服務器名稱和數據庫路徑,而無需編譯項目。這允許在隨機計算機上正確設置數據庫連接參數。

解決方案:

  1. 安裝設計時的數據庫連接組件,不要在運行時創建它。設置所有參數,包括服務器名稱,數據庫路徑,字符集等到您的數據庫的工作副本。這將允許您在設計時設置與此數據庫關聯的其他組件。 (在你的回答中,我看到你做的幾乎一樣。)

  2. 將服務器名稱,數據庫路徑和任何其他參數保存到外部資源,ini文件,Windows註冊表或其他內容中。然後在應用程序啓動時或連接到數據庫之前獲取這些參數。

    在你的情況下,你使用本地服務器和應用程序相同的路徑,所以你不需要存儲任何東西。

至於問題

的代碼:

with FDConnection1 do begin 
    Close; 
    with Params do begin 
    Clear; <-- this removes all parameters 
    Add('DriverID=SQLite'); 
    Add('Database='+path+'Data\sqlite.db'); 
    end; 
    Open; 
end; 

去除除了DriverIDDatabase所有其他參數。可能是由此產生的錯誤。

如果你已經在FDConnection設置所有參數:

不要使用:

FDConnection.Params.Add('Database='+path+'Data\sqlite.db'); 

這將增加新的參數名稱相同,但連接將使用第一個。

這就解釋了爲什麼一切都在你的答案的作品,因爲你沒有設置設計時參數「數據庫」:

第三步是砸FDConnection的數據模塊,並設置所有 參數EXCEPT數據庫文件。

而是使用:

FDConnection.Params.Database := 'Database='+path+'Data\sqlite.db'; 

您可以在 OnDataModuleCreateFDConnectionBeforeConnect事件

使用例如我希望這將是有益的。

+0

解釋和代碼非常感謝,謝謝。幫助我改進我的解決方案。 – Mathmathou

0

在Android中,我無法fdConnection在設計時打開編譯,然後證明它關閉。你的第一行並沒有爲我的工作,但需要的目標:用以下公式

,它爲我工作:

FdConnection1.Params.Values['Database'] := GetHomePath 
     + PathDelim + 'sqlite.db'; 

看,我沒有使用的子文件夾「數據」。你可以先嚐試簡單。

+0

裏卡多,感謝您的提示。但getHomePath通向Appdata/Roaming文件夾,數據庫存儲在應用程序文件夾的子文件夾中,這就是我使用ExtractFilePath命令的原因。該應用程序是可移植的,該文件夾可以放在任何地方的用戶。 – Mathmathou

0

如果您的資源對最終用戶來說很簡單並且可讀,您可以將它們直接打包到exe文件中。這將給你真正的便攜式應用程序,你的用戶可以從任意位置運行,甚至從USB閃存。

轉到項目 - >資源和圖像菜單,添加你的文件。

你可以用T流訪問它們在運行時:

var 
    s: TStream; 
    {.....} 
    s:=TResourceStream.Create(hinstance, 'myfile_1', RT_RCDATA); 

有些資源可以處理內存中直接。至於SQLite數據庫,你可以從應用程序的資源複製到用戶的文檔路徑:

MyAppPath := Tpath.GetDocumentsPath+'\MyAppName'; // you need System.IOUtils in uses 
    If not DirectoryExists(MyAppPath) then CreateDir(MyAppPath); 
    MyDBPath := MyAppPath+'\Data\sqlite.db'; 
    If not FileExists(MyDBPath) then begin 
    FL:=TFileStream.Create(MyDBPath ,fmCreate); 
    FL.CopyFrom(s,0); // this will copy your db into 'sqlite.db' file 
    end; 
+0

感謝您的提示,我一定會考慮未來的項目。在這一個上,圖像和圖標等資源被嵌入到共享單元上的TImageList中 – Mathmathou

1

當我發現我自己的解決方案,我決定把它張貼在這裏對誰可能會遇到同樣的問題(也就是未來用戶說一個Delphi初學者級別和需要鏈接數據庫文件相對於他們的項目exe文件)。

第一步是爲項目添加一個數據模塊。這是通過將文件中完成 - >新建 - >其他 - > Delphi的文件 - >數據模塊 enter image description here

第二步驟一旦添加到項目中,作爲我的主要應用形式的數據模塊使得該呼叫創建數據庫時,我必須確保數據模塊是首先創建的。爲了更好地實現這一點,我去項目 - >選項 - >形式與自動列表的第一個位置拖到數據模塊創建的表單 enter image description here

第三步驟是砸FDConnection的數據模塊,並設置所有參數數據庫文件除外

第四步是爲數據模塊添加一個OnCreate事件,以指定數據庫相對於應用程序exe和連接的路徑。有人做過這樣的:

​​

第五步也是最後一步是對數據模塊添加到需要對數據庫的連接所有其他設備的使用條款。

我意識到,這個解決方案遠非完美,而且,正如非常有經驗的用戶所述,將數據庫存儲在與主應用程序Exe相同的文件夾(或子文件夾)中並不是一個好的解決方案。

此外,我決定連接到DataModule創建的數據庫,但另一種解決方案可能是在觸發查詢然後斷開連接之前按需連接。這是給你和你的需求

感謝所有您的幫助,提示和建議

數學

PS:請注意我沒有檢查我的答案接受爲最佳答案,也不會公平權:-)

+0

我不認爲在啓動應用程序時需要創建所有這些表單。當需要時創建表單並在不再需要時將其銷燬 –

+0

@ValMarinov感謝您的建議(再次感謝您的其他答案非常有用,尤其是關於指定數據庫參數而不是添加它的評論)。在創業時創建所有表單有什麼缺點?內存使用情況 ?我認爲在啓動時不創建它們將不會對exe文件大小產生影響,所以它只是一個記憶的東西?對不起,如果這個問題似乎有點「noobish」:) – Mathmathou

+0

內存,yes.Also這可能會導致應用程序啓動時間延長,尤其是。如果表單包含它自己的數據庫訪問。還有更多的東西。一般來說,接受它是一種良好的習慣,會讓你的生活更輕鬆。 :)看到這個:http://www.ayton.id.au/gary/it/Delphi/D_Forms1.htm –