2013-03-01 103 views
5

我有一個使用ODBC DSN連接到目標數據庫的Delphi 6應用程序。我想包含列出DSN連接到的數據庫名稱的文本。我嘗試使用SQL命令db_name(),但只有收到零響應,儘管它在登錄到SQL服務器時有效。需要標識ODBC DSN連接的應用程序中的數據庫名稱

Delphi中有一種方法可以識別我連接的數據庫嗎?我能拉起sys.databases中的表,但我不能確定如何確定哪些數據庫是一個我連接到

爲例:

如果我連接到DSN LocalDSN我希望能夠向用戶顯示他們已連接到數據庫,其中數據庫是他們正在與之通信的sql數據庫的名稱。

+4

您不能通過sql獲取DSN名稱,因爲AFAIK引擎本身並不知道您用於連接的機制,但您肯定可以從它駐留在連接對象中的屬性中獲取它使用。例如,如果您使用TSQLConnection,它將存儲在參數上。 – jachguate 2013-03-01 00:17:34

+0

不幸的是,連接對象似乎只有三個屬性 - dsn的名稱和用戶的用戶名和密碼。 應用程序正在使用TQuery和TDatabase對象(都來自vcl),如果有幫助 – ChargerIIC 2013-03-01 14:54:09

+0

@jachguate你應該做出答案。 – 2013-03-01 15:31:17

回答

3

ODBC DSN存儲在Windows註冊表中。請記住,Windows註冊表以及ODBC DSN設置在32位和64位版本之間是分開的。您可以通過HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\[YOUR_DSN_NAME]訪問此信息,然後讀取值DatabaseServer以瞭解數據庫或服務器名稱。

可以讀取服務器和數據庫名稱與這些功能:

uses 
    Registry; 

function ServerOfDSN(const Name: String): String; 
var 
    R: TRegistry; 
    K: String; 
begin 
    K:= 'Software\ODBC\ODBC.INI\'+Name; 
    R:= TRegistry.Create(KEY_READ); 
    try 
    R.RootKey:= HKEY_LOCAL_MACHINE; 
    if R.KeyExists(K) then begin 
     if R.OpenKey(K, False) then begin 
     if R.ValueExists('Server') then 
      Result:= R.ReadString('Server'); 
     R.CloseKey; 
     end; 
    end; 
    finally 
    R.Free; 
    end; 
end; 

function DatabaseOfDSN(const Name: String): String; 
var 
  R: TRegistry; 
  K: String; 
begin 
    K:= 'Software\ODBC\ODBC.INI\'+Name; 
    R:= TRegistry.Create(KEY_READ); 
    try 
    R.RootKey:= HKEY_LOCAL_MACHINE; 
    if R.KeyExists(K) then begin 
     if R.OpenKey(K, False) then begin 
     if R.ValueExists('Database') then 
      Result:= R.ReadString('Database'); 
     R.CloseKey; 
     end; 
    end; 
    finally 
    R.Free; 
    end; 
end; 

根據什麼數據庫引擎和您正在使用的驅動程序,此註冊表項中的內容可能會有所不同,因此有可能該ServerDatabase可能不是您需要的註冊表值,但自己檢查並在註冊表中找到您的值名稱以知道如何讀取它。

+0

注意:由於對問題的最初解釋錯誤,因此我只包含服務器名稱。我最初以服務器名稱回答,後來當我意識到這就是要求的時候添加了數據庫名稱。 – 2013-03-02 03:03:05

+0

找到我的操作系統的64位部分下的設置。我將能夠從那裏獲取應用程序,以及數據庫名稱的32位位置。謝謝! – ChargerIIC 2013-03-04 15:00:00

1

您可以使用SQLGetPrivateProfileString ODBC API來獲取創建的DSN的內容。

int SQLGetPrivateProfileString( 
LPCSTR lpszSection, 
LPCSTR lpszEntry, 
LPCSTR lpszDefault, 
LPCSTR RetBuffer, 
INT  cbRetBuffer, 
LPCSTR lpszFilename); 

這裏,

lpszSection =註冊表部分您想了解詳細信息。這將是您的案例中的DSN名稱。

lpszEntry =你想從中提取價值的鑰匙。您想獲取數據庫名稱信息,因此您需要檢查註冊表項HKEY_LOCAL_MACHINE \ Software \ ODBC \ ODBC.INI [YOUR_DSN_NAME]以知道存儲數據庫名稱信息的密鑰名稱是什麼。這是因爲不同的驅動程序可以有不同的密鑰名稱來存儲數據庫名稱。

lpsz默認 =如果未找到密鑰,則在最後一個參數(lpszEntry)中指定的密鑰的默認值。

RetBuffer =指向指定密鑰的接收值的輸出緩衝區的指針。

cbRetBuffer = RetBuffer指向的緩衝區大小,以字符爲單位。

lpsz文件名 =文件名,你在這裏搜索這些條目。在你的情況下它將是odbc.ini。

樣品例如

CHAR *dsn_name = "Your DSN name"; 
CHAR db_name[20]; 
char *odbcini = NULL; 
odbcini = "odbc.ini"; 

SQLGetPrivateProfileString(dsn_name, (CHAR*)"DATABASE", (CHAR*)"", db_name, 
sizeof(db_name), odbcini); 

它將搜索註冊表項HKEY_CURRENT_USER或HKEY_LOCAL_MACHINE或兩者取決於配置模式設置(可以使用SQLSetConfigMode ODBC API來設置)。如果mode沒有明確設置,它將搜索HKEY_CURRENT_USER和HKEY_LOCAL_MACHINE。 欲瞭解更多信息,請參閱https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetprivateprofilestring-function

相關問題