⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 说明.txt

📁 提供一种自动加载ODBC数据源的方法,仅供参考
💻 TXT
字号:
在使用VC、VB、Delphi等高级语言编写数据库应用程序时,往往需要用户自己在控制面板中配置ODBC数据源。对于一般用户而言,配置ODBC数据源可能是一件比较困难的工作。而且,在实际应用中,用户往往要求在同一个应用程序中访问不同的数据源,因此采用一般的加载方法就有了无法克服的缺陷。为能在程序中完成这一工作,方便应用程序的使用,本文以VC为开发环境介绍两种在应用程序中动态加载ODBC系统数据源的方法。 

方法一:修改注册表 

设计思路 

  一般情况下,当用户在控制面板中配置好ODBC数据源后,Windows系统便在注册表中加入了一些子键来存储用户的配置结果。当应用程序需要用到数据源时,Windows便会通知底层接口查阅注册表中该数据源的配置。如果用户删除了某个ODBC数据源,那么也会在注册表中有所反应。如果配置的数据源是用户数据源, Windows系统便会修改注册表的HKEY_CURRENT_USER\SOFTWARE\ODBC\ODBC.INI子键;如果配置的数据源是系统数据源,Windows系统便会修改注册表的HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI主键。因此,我们可以在应用程序中使用Windows API中的注册表编辑函数来完成Windows所做的工作,这样就可以达到动态加载数据源的目的。 

具体实现 

  对于不同类型的数据源,注册表的修改也各有不同,但基本上都要修改两个地方。一个是在 ODBC.INI子键下建立一个与数据源描述名同名的子键,并在该子键下建立与数据源配置相关的项;另一个是在ODBC.INI\ODBC Data Sources子键下建立一个新项以便告诉驱动程序管理器ODBC数据源的类型。下面以配置一个Microsoft Access数据源为例给出实现此功能的函数的代码。 

/*strSourceName是要创建的数据源名,strSourceDb是数据库存放路径,strDescription是数据源的描述字符串。*/ 

BOOL CLoadOdbcDlg::LoadDbSource(CString strSourceName, CString strSourceDb, CString strDescription) 
{ 
 //存放打开的注册表键 
 HKEY hKey; 
 DWORD dw; 

 //存放注册表API函数执行的返回值 
 LONG lReturn; 

 //存放要打开的子键 
 CString strSubKey; 

 //检测是否安装了MS Access ODBC driver:odbcjt32.dll 
 //获得 Windows系统目录 
 char sysDir[MAX_PATH]; 
 char drvName[]="\\odbcjt32.dll"; 
 ::GetSystemDirectory(sysDir, MAX_PATH); 
 strcat(sysDir,drvName); 
 CFileFind findFile; 
 if(!findFile.FindFile(sysDir)) 
 { 
  AfxMessageBox("您的计算机系统中没有安装MS Access的ODBC驱动程序odbcjt32.dll,您将无法加载该类数据源。" ,MB_OK | MB_ICONSTOP); 
  return false; 
 } 

 strSubKey="SOFTWARE\\ODBC\\ODBC.INI\\" + strSourceName; 
 //创建 ODBC数据源在注册表中的子键 
 lReturn=::RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)strSubKey, 0, NULL, REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dw); 
 if(lReturn != ERROR_SUCCESS) 
  return false; 

 //设置数据源的各项参数 
 CString strDbq = strSourceDb; 
 CString strDriver = sysDir; 
 DWORD dwDriverId = 25; 
 CString strFil = "MS Access;"; 
 CString strPwd = strSourceName; 
 DWORD dwSafeTransactions = 0; 
 CString strUid = strSourceName; 
 ::RegSetValueEx(hKey, "DBQ", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strDbq), strDbq.GetLength()); 
 ::RegSetValueEx(hKey, "Description", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strDescription), strDescription.GetLength()); 
 ::RegSetValueEx(hKey, "Driver", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strDriver), strDriver.GetLength()); 
 ::RegSetValueEx(hKey, "DriverId", 0L, REG_DWORD, (CONST BYTE*)(&dwDriverId), sizeof(dw)); 
 ::RegSetValueEx(hKey, "FIL", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strFil),strFil .GetLength ()); 
 ::RegSetValueEx(hKey, "PWD", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strPwd),strPwd.GetLength ()); 
 ::RegSetValueEx(hKey, "SafeTransactions", 0L, REG_DWORD, (CONST BYTE*)(&dwSafeTransactions), sizeof(dw)); 
 ::RegSetValueEx(hKey, "UID", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strUid),strUid.GetLength()); 
 ::RegCloseKey(hKey); 

 //创建 ODBC数据源的Jet子键 
 strSubKey += "\\Engines\\Jet"; 
 lReturn = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)strSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dw); 
 if(lReturn != ERROR_SUCCESS) 
  return false; 

 //设置该子键下的各项参数 
 CString strImplict=""; 
 CString strUserCommit="Yes"; 
 DWORD dwPageTimeout=5; 
 DWORD dwThreads=3; 
 DWORD dwMaxBufferSize=2048; 
 ::RegSetValueEx(hKey, "ImplicitCommitSync", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strImplict), strImplict.GetLength()+1); 
 ::RegSetValueEx(hKey, "MaxBufferSize", 0L, REG_DWORD, (CONST BYTE*)(&dwMaxBufferSize), sizeof(dw)); 
 ::RegSetValueEx(hKey, "PageTimeout", 0L, REG_DWORD, (CONST BYTE*)(&dwPageTimeout), sizeof(dw)); 
 ::RegSetValueEx(hKey, "Threads", 0L, REG_DWORD, (CONST BYTE*)(&dwThreads), sizeof(dw)); 
 ::RegSetValueEx(hKey, "UserCommitSync", 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strUserCommit), strUserCommit.GetLength()); 
 ::RegCloseKey(hKey); 

 //设置ODBC数据库引擎名称 
 lReturn=::RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\ODBC\\ODBC.INI\\ODBC Data Sources", 0L, KEY_WRITE, &hKey); 
 if(lReturn != ERROR_SUCCESS) 
  return false; 
 CString strDbType="Microsoft Access Driver (*.mdb)"; 
 ::RegSetValueEx(hKey, strSourceName, 0L, REG_SZ, (CONST BYTE*)((LPCTSTR)strDbType), strDbType.GetLength()); 

 return true; 
} 

由于在动态加载中,一般只会改变数据库文件、数据源说明以及数据源描述,故上述函数可以实现应用中的大部分要求。如果应用中还需要作更多的改变,那么也可以通过改变函数参数的方式加以实现。对于需要动态加载多种类型数据源的情况,可以用具有不同参数的重载函数去实现。 

方法二:利用DLL 

设计思路 

  Windows系统子目录中的动态链接库Odbcinst.dll提供了一个可以动态地增加、修改和删除数据源的函数SQLConfigDataSource()。该函数的原型如下: 

  BOOL SQLConfigDataSource(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes); 

hwndParent参数是父窗口句柄。如果该值为NULL,将不会显示与父窗口有关的对话框。 

fRequest参数可以设置为下面的数值之一: 

 ODBC_ADD_DSN:增加一个新的用户数据源; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -