需要标识ODBC DSN连接的应用程序中的数据库名称

问题描述:

我有一个使用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

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

您可以使用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