在项目过程中,需要使用数据库,所以用到了自动配置数据源的问题。因此从网上查了方法,这方面的介绍很多。
总的来说就是使用SQLConfigDataSource。
1、ODBC API提供了动态创建数据源的函数SQLConfig DataSource。该函数的原型如下:
BOOL SQLConfigDataSource ( HWND hwndParent,WORD fRequest,
LPCSTR lpszDriver,LPCSTR lpszAttributes );
参数说明如下:
(1)参数hwndParent用于指定父窗口句柄,在不需要创建数据源对话框时,可以将该参数指定为NULL。
(2)参数fRequest用于指定函数的操作内容,取值如下:
ODBC_ADD_DSN: 加入一个新的用户数据源;
ODBC_CONFIG_DSN:修改一个存在的用户数据源;
ODBC_REMOVE_DSN:除一个存在的用户数据源;
ODBC_ADD_SYS_DSN:增加一个新的系统数据源;
ODBC_CONFIG_SYS_DSN:配置或者修改一个存在的系统数据源;
ODBC_REMOVE_SYS_DSN:删除一个存在的系统数据源;
ODBC_REMOVE_DEFAULT_DSN:删除省缺的数据源说明部分。
(3)参数lpszDriver用于指定ODBC数据源的驱动
程序类别,例如,为了指定Access数据源,该参数应赋以字符串“Microsoft Access Driver(*.mdb)\0”;对SQL SERVER数据源,则应赋以字符串“SQL Server”。
(4)参数lpszAttributes用于指定ODBC数据源属性。例如:
① 对Access数据源:
"DSN= MYIMAGE\0 DBQ=D:\\ImageProcess\\image.mdb\0
DEFAULTDIR= D:\\ImageProcess\0\0"
说明:该字符串指定数据源名称(DNS)为MYIMAGE;数据库文件(DBQ)为D:\\ImageProcess\\image.mdb ;缺省数据库文件路径(DEFAULTDIR) 为D:\\ImageProcess 。
② 对SQL SERVER数据源:
"DSN=MYIMAGE\0 SERVER=MYET\0 DATABASE=Image"
说明:该字符串指定数据源名称(DSN)为MYIMAGE;SQLSERVER 数据库服务器名(SERVER)为 MYET;数据库名称(DATABASE)为Image。
2、关于第四个参数字符串的设置问题
上面的函数用法在网上有很多详细的介绍,大家可以自己查阅,我主要是讲一下我在工程中碰到的一个问题,花了很多时间,网上介绍的比较少也比较模糊,希望对碰到同样问题的朋友有帮助。
在使用参数连接数据库的时候,我的程序是这样的:
if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN,_T("SQL Server"),IP_ADDRESS_SAVE_USER_PASSWORD))
{
AfxMessageBox(_T("数据源SAVE_USER_PASSWORD添加失败!"));
}
但是软件写好了之后服务器的IP地址是可能会改变的,我不可能每一次改变都得到程序里修改IP地址,所以我会留出一个设置界面传送IP地址字符串,最终将从编辑框传入的IP地址字符串组合到 IP_ADDRESS_SAVE_USER_PASSWORD中,再传给函数的第四个参数。
这个地方特别需要注意的一点(我在这里困惑了好久),如果先将字符串给变量再传给参数,变量的类型必须是LPCWSTR(在UNICODE下),如果变量用了CString是无法成功的。
if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN,_T("SQL Server"),_T("DSN=SAVE_PASSWORD_TELNET\0 SERVER=192.168.1.111\0 DATABASE=DATABASE_LOGIN\0")))
这个语句没有问题,可以成功配置数据源。但是,下面这个语句就不行了
CString str =_T("DSN=SAVE_PASSWORD_TELNET\0 SERVER=192.168.1.111\0 DATABASE=DATABASE_LOGIN\0");
if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN,_T("SQL Server"), str))
因为需要组合字符串,所以想要先给变量再传给函数。
实验了很多次之后,也参考了几个网上的方法,都没有成功。对于字符变量类型之间的转换真是很头疼,没办法,经过多次试验研究后发现,变量类型必须是LPCWSTR,希望对大家有帮助吧。
改后的程序如下:
LPCWSTR str =_T("DSN=SAVE_PASSWORD_TELNET\0\0 SERVER=192.168.1.111\0\0 DATABASE=DATABASE_LOGIN\0\0");
if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN,_T("SQL Server"), str))
{
AfxMessageBox(_T("数据源SAVE_USER_PASSWORD添加失败!"));
}
3、关于组合几段字符串的问题
上面的问题到此并没有结束,别忘了我的目的是要将传入的IP地址字符串组合到str这个参数字符串中,那么怎么办呢?
其实,在MFC的UNICODE宽字符环境下,各种定义的字符类型让人眼花缭乱。追寻字符的原始定义我们发现,其实CString和LPCWSTR都是来自于基本宽字符类型wchar_t,那么我们只需要对wchar_t类型进行操作就行了。
wchar_t str1 = _T("DSN = GPS_TELNET: SERVER =");
wchar_t str2 = _T("192.168.1.111");
wchar_t str3 = _T(": DATABASE=GPS:");
wcscat(str1,str2);
wcscat(str1,str3);
int mlen = wcslen(str1);
for(int i=0;i
{
if(str1[i] == ':')
str[i] = '\0';
}
if(!SQLConfigDataSource(NULL,ODBC_ADD_DSN,_T("SQL Server"), str1))
{
AfxMessageBox(_T("数据源SAVE_USER_PASSWORD添加失败!"));
}
这样就可以了。因为SQLConfigDataSource的第四个参数是一个字符串,而且字符串中间要有\0,但是字符串将\0视为字符串结尾标志,所以我们在组合的时候使用了:代替,然后组合完成之后在用\0替换回来。
经过测试上面的代码完全通过,哈哈。有问题的朋友可以留言讨论,希望对用着的朋友有帮助。