CDatabase db;if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN, "Microsoft FoxPro Driver (*.dbf)", "DSN=MYDB\0""DefaultDir=c:\\mydir\0""FIL=FoxPro 2.5\0""DriverId=280\0")){AfxMessageBox("Can't add DSN!");return ;}TRY{db.Open("MYDB");}CATCH(CDBException, e){AfxMessageBox(e->m_strError);return;}
解决方案 »
- 求<< TCP/IP Sockets编程(C语言实现)(第2版)>>中文版 pdf 电子书
- 波浪 能用 OpenGL中的简单 光照来渲染吗 ?
- OLE库初始化失败,为什么会这样...有人可以告诉我么,加急.
- 如何在两个工程之间调用函数
- 关于获得菜单资源的问题
- 急,简单---在线等 没有把这段程序运行完,则另外处理的问题
- 各位兄台帮忙(调试)
- 有没有详细讲解打印控制的书
- 关于 keybd_event 函数,调时不能即时响应!
- 关于对话框的一个问题,很简单,可以得分。
- QQ自带的腾讯浏览器可以列出当前网站上使用qq的人,这是怎么做到的?(不知道贴对了地方没有)
- 急!为什么在Dll中无法调用AfxGetInstanceHandle()函数
我查了MSDN,找到了相关题目:Using ODBC API Functions
一共有4个API函数可用。
if(SQLConfigDataSource(m_pMainWnd->m_hWnd,ODBC_ADD_DSN,"Microsoft Access Driver (*.mdb)",
"DSN=Personnel\0"
"DBQ=C:\\My Documents\\dq.mdb\0"
"DefaultDir=C:\\My Documents\0"
"Driver={Microsoft Access Driver (*.mdb)}\0"
"DriverId=790\0"
"Deleted=1\0"
"Description=兵营房屋信息ODBC数据源\0"
"FileType=Access\0"
"JetIniPath=odbcddp.ini\0"
"MaxScanRows=20\0"
"MaxBufferSize=512"
"ImplicitCommitSync=No\0"
"UserCommitSync=No\0"
"Exclusive=1\0"//独占
"ReadOnly=1\0"//只读
"UID=Smith\0"
"SafeTransactions=0\0"
"PWD=Sesame\0"
"DATABASE=dq\0"
"ExtendedAnsiSQL=1\0"
"Statistics=0\0"
"\0"))
AfxMessageBox("创建成功!");
else
AfxMessageBox("取消创建或创建失败!");
SQLConfigDataSource 函数被用于动态地添加、修改或删除数据源,该函数使用下列关键字。关键字 描述
CHARACTERSET:
对于 Text 驱动程序,OEM 或 ANSI。
COLLATINGSEQUENCE:
字段排序的顺序。当使用 dBASE 驱动程序时,这个序列可以是: ASCII (缺省) 或 International.当使用 Paradox 驱动程序时,这个序列可以是: ASCII (缺省),International,Swedish-Finnish,或Norwegian-Dan ish.这将设置与“设置”对话框的“排序顺序”控件相同的选项。
COLNAMEHEADER:
对于 Text 驱动程序,指出数据的第一个记录是否将指定列名。其值为 TRUE 或 FALSE。
COMPACT_DB:
对于 Microsoft Access data compaction驱动程序,在数据库文件上执行数据库压缩。有如下的格式:COMPACT_DB=<路径名><可选排序顺序><可选 ENCRYPT 关键字>.
CREATE_DB:
对于 Microsoft Access 驱动程序,创建数据库文件。有如下的格式:CREATE_DB=<路径名>><可选排序顺序><可选 ENCRYPT 关键字,在这里路径名是一个 Microsoft Access 数据库的完整路径。如果路径名指到现有数据库,则将返回错误。排序顺序如“添加数据库”对话框中所设置,且在按下“Microsoft Access 安装”对话框的“创建”按钮时显示此对话框会。如果没有指定排序顺序,则使用 General。当使用 CREATE_DB 关键字时,如果要创建的 Microsoft Access 数据库的路径名称包含一个或一个以上的空格,则必须将整个路径名称用双引号括起来,如下列示例显示:"C:\PROGRAM FILES\COMMON FILESMyAccess.mdb""C:\PROGRAM FILES\Access2.mdb"CREATE_DB=C:\TEMP\test.mdb(不需要双引号)
CREATE_SYSDB:
对于 Microsoft Access 驱动程序,创建系统数据库文件。有如下的格式:CREATE_SYSDB=<路径名>><可选排序顺序>,在这里路径名是一个 Microsoft Access 数据库的完整路径。如果路径名指到现有数据库,则将返回错误。排序顺序如“添加数据库”对话框中所设置,且在按下“Microsoft Access 安装”对话框的“创建”按钮时显示此对话框会。如果没有指定排序顺序,则使用 General。
CREATE_V2DB:
对于 Microsoft Access 驱动程序,创建与 Microsoft Access 2.0 兼容的数据库文件。有如下的格式:CREATE_V2DB=<路径名>><可选排序顺序>,在这里路径名是一个 Microsoft Access 数据库的完整路径。如果路径名指到现有数据库,则将返回错误。排序顺序如“添加数据库”对话框中所设置,且在按下“Microsoft Access 安装”对话框的“创建”按钮时显示此对话框会。如果没有指定排序顺序,则使用 General。当使用 CREATE_V2DB 关键字时,如果要创建的 Microsoft Access 数据库的路径名称包含一个或一个以上的空格,则必须用双引号将整个路径名称括起来,如下列示例显示:"C:\PROGRAM FILES\COMMON FILESMyAccess.mdb""C:\PROGRAM FILES\Access2.mdb"CREATE_V2DB=C:\TEMP\test.mdb(不需要双引号)
DBQ 对于 Microsoft Access 或 Paradox 驱动程序,数据库文件的名称。对于 Microsoft Excel 驱动程序,当访问 Microsoft Excel 5.0、7.0 或 97 的文件时,工作簿文件的名称。这就设置了与“设置”对话框的“数据库”控件相同的选项。
DEFAULTDIR:
对于数据库文件( Microsoft Access 驱动程序) 或 目录 (dBASE,Microsoft Excel,Paradox,或 Text 驱动程序)的路径指定。这就设置了与“设置”对话框的“选择目录”控件,或对于 Microsoft Excel,“设置”对话框的“选择工作簿”控件相同的选项。
DELETED:
对于 dBASE 驱动程序,指定被标记为已删除的行是否可以被检索到或被放置。如果设置成 1,则不显示被删除的行;如果设置成 0,则把已删除的行当作未删除的行。默认值是 不选定。这就设置了与“设置”对话框的“显示删除列”控件相同的选项。
DESCRIPTION:
数据源中数据的描述。这就设置了与“设置”对话框的“描述”控件相同的选项。
DRIVER:
指向驱动程序 DLL 的路径说明。
DRIVERID:
对于驱动程序的整型标识符。
25 (Microsoft Access)
21 (dBASE III)
277 (dBASE IV)
533 (dBASE 5.0)
534 (Microsoft Excel 3.0)
278 (Microsoft Excel 4.0)
22 (Microsoft Excel 5.0/7.0)
790 (Microsoft Excel 97)
26 (Paradox 3.x)
282 (Paradox 4.x)
538 (Paradox 5.x)
27 (Text)
EXCLUSIVE:
决定数据库将以独占方式(一次只有一个用户访问)或分享方式(一次有多个用户访问)打开。可以是 TRUE(独占方式)或 FALSE(分享方式)。(这不会应用到 Microsoft Excel 或 Text 驱动程序)。这就设置了与“设置”对话框的“独占方式”控件相同的选项。
EXTENSIONS:
列出在数据源上“文本文件”的文件名的文件扩展名。这就设置了与“设置”对话框的“文件类型”控件相同的选项。
FIL:
文件类型
MS Access for Microsoft Access
dBase III,dBase IV,or dBase 5
Excel 3.0,4.0,5.0,7.0,or 97 for Microsoft Excel
Paradox 3.x,4.x,or 5.x)
Text.
FILETYPE:
对于 Text 驱动程序(文本)的文件类型。
FIRSTROWHASNAMES:
对于 Microsoft Excel 驱动程序,指出范围中第一行的单元格包含了表的列名 (1) 还是没有包含 (0)。
FORMAT:
对于 Text 驱动程序,可以是 FIXEDLENGTH、TABDELIMITED、CSVDELIMITED(用逗点分隔)或DELIMITED ( )(用括号中指定的特殊字符分隔)。特殊字符是长度为 1 的字符,并且可以是字符、十进制或十六进制格式。
IMPLICITCOMMITSYNC 决定 Microsoft Access 驱动程序是否将异步执行内部或隐含提交。最初将此值设置成“是” Microsoft Access 驱动程序将等待提交要完成的内部/隐含事务。不应轻率更改此选项的值。有关此选项的更多信息,参见 Microsoft Jet 数据库引擎程序员指南。这就设置了与“设置”对话框的 ImplicitCommitSync 控件相同的选项。
MAXBUFFERSIZE:
Microsoft Access 用来与磁盘传送数据的内部缓冲区大小,以 KB 为单位。缺省缓冲区大小是 512 K(显示为 512)。可用任何被 256 整除的整型值。这就设置了与“设置”对话框的“缓冲区大小”控件相同的选项。
MAXSCANROWS 对于 Microsoft Access、Microsoft Excel 或 Text 驱动程序,在根据现有数据来设置列的数据类型时,所扫描的行数。可以输入由 1 到 16 的数字作为扫描的行数。默认值为 8;如果将它设置成 0,则扫描全部行。(越界的数字将返回错误)。对于 Text 驱动程序,可输入由 1 到 32767 的数字为扫描的行数;不过,默认值总是 25。(越界的数字将返回错误)。这就设置了与“设置”对话框的“扫描”控件相同的选项。
PAGETIMEOUT 指定一页(如果不使用)在删除之前保持在缓冲区中的时间的长短,以十分之一秒为单位。对于 Microsoft Access 驱动程序,默认值是 5 个十分之一秒(0.5 秒)。对于dBASE 和 Paradox 驱动程序,缺省值是1秒的600/10 (60秒).注意,此选项应用于所有使用 ODBC 驱动程序的数据源。这就设置了与“设置”对话框的“页超时”控件相同的选项。
PARADOXNETPATH:
对于 Paradox 驱动程序,包含 Paradox 锁定数据库的目录的完整路径,因为它包含 PDOXUSRS.net 文件 (Paradox 4.x) 或 PARADOX.net 文件 (Paradox 5.x)。如果其中一个文件未包含在目录中,Paradox 驱动程序将创建一个。关于这些文件的详细信息,请参阅 Paradox 文档。在可以选定网络目录之前,必须输入 Paradox 用户名称。这就设置了与 Paradox“设置”对话框的“选定网络目录”控件相同的选项。
PARADOXNETSTYLE 对于 Paradox 驱动程序,当存取 Paradox 数据时使用的网络存取方式是:对于 Paradox 3.x 用“3.x”或 对于 Paradox 4.x 或 5.x 用“4.x”。如果版本是 Paradox 4.x 或 5.x,可以设置成“3.x”或“4.x”;如果版本是 Paradox 3.x,样式必须是“3.x”。这就设置了与 Paradox“设置”对话框的“网络样式”控件相同的选项。
PARADOXUSERNAME:
对于 Paradox 驱动程序,Paradox 用户名称。这就设置了与 Paradox“设置”对话框的“用户名称”控件相同的选项。
PWD:
对于 Microsoft Access 或 Paradox 驱动程序,密码。对于 Paradox 驱动程序,这是可选的关键字,而且驱动程序不会将它写到文件中。用它调用 SQLDriverConnect,与有密码安全的 Paradox 文件相对。
READONLY:
TRUE 使文件为只读;FALSE 使文件不是只读。这就设置了与“设置”对话框的“只读”控件相同的选项。
REPAIR_DB:
对于 Microsoft Access repairs a database驱动程序,在提交进程期间失败而损害的数据库修复。
STATISTICS:
对于 dBASE 驱动程序,确定表大小统计是否是近似的。注意,此选项应用于所有使用 ODBC 驱动程序的数据源。这就设置了与“设置”对话框的“近似(行)计数”控件相同的选项。
SYSTEMDB:
对于 Microsoft Access 驱动程序,指向系统数据库文件的路径规范。这就设置了与“设置”对话框的“系统信息库”控件相同的选项。
THREADS:
使用引擎的背景线程数。对于 Microsoft Access 驱动程序,默认值为 3,但可以更改。对于dBASE,Microsoft Excel,Paradox,和 Text 驱动程序,这个值是3,并且不能被改变。这就设置了与“设置”对话框的“线程”控件相同的选项。
UID:
对于 Microsoft Access 驱动程序,用于登录的用户 ID名称。
USERCOMMITSYNC:
决定 Microsoft Access 驱动程序是否将异步执行用户定义的事务。最初将此值设置成 “Yes”,表示 Microsoft Access 驱动程序将等待提交已完成的用户定义的事务。不应轻率更改此选项的值。有关此选项的更多信息,参见 Microsoft Jet 数据库引擎程序员指南。这就设置了与“设置”对话框的 UserCommitSync 控件相同的选项。
ODBCINST.H,我包含了它结果连接时出错了。
在VC中动态加载 ODBC的方法
武汉理工大学信息工程学院 陈建勇 袁景凌
在使用 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," ImplictCommitSync" ,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* )((LCTSTR)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:增加一个新的用户数据源;
ODBC_CONFIG_DSN:修改(配置)一个已经存在的用户数据源;
ODBC_REMOVE_DSN:删除一个已经存在的用户数据源;
ODBC_ADD_SYS_DSN:增加一个新的系统数据源;
ODBC_CONFIG_SYS_DSN:修改 (配置 )一个已经存在的系统数据源;
ODBC_REMOVE_SYS_DSN:删除一个已经存在的系统数据源。
lpszDriver参数用于传递数据库引擎的名字,等同于方法一中 strDbType变量。
lpszAttirbutes参数是关键字的值,即一连串的 " keyname=value"字符串,每两个字符串之间用 " \"隔开,如 DSN=Personnel Data\0UID=Smith\0DATABASE=Personnel。关于该参数的详细设置请参阅 MSDN中 SQLConfigDataSource()函数的帮助文档和各种 ODBC驱动程序文档。
具体实现
由于 VC的缺省库文件中不包含 SQLConfigDataSource()函数,因此使用该函数之前需要将 odbcinst.h文件包含在工程的头文件中,在工程的 Settings属性对话框 Link属性页的 Object/library modules编辑框中增加 odbc32.lib,同时保证系统目录 system32下有文件 odbccp32.dll。
仍以 Microsoft Access为例,设置数据源名为 demo,数据源描述为 "示例数据源 ",那么在需要动态加载数据源的地方加入下列代码即可:
::SQLConfigDataSource (NULL,ODBC_ADD_SYS_DSN," Microsoft Access Driver (* .mdb)"," DSN=demo\0Descirption=示例数据库 " );
小结
上述两种方法都可以实现动态加载各种类型的 ODBC数据源,并且在 Windows95/98/NT/2000环境下调试通过。方法一在实现时需要较多的代码,方法二所需代码虽少,但需要额外文件的支持,而且随着数据源配置的灵活性的增加,为了形成 lpszAttributes字符串,其代码长度也会相应增加。由于从控制面板配置数据源使得程序员可以获得更加直观的理解,所以对于注册表中各项值以及相应项名称的获得除了可以查阅相关驱动程序的文档外,程序员也可以在编程前先通过控制面板配置 ODBC数据源,然后根据注册表中相应部分的内容进行编程。