网站首页  词典首页

请输入您要查询的论文:

 

标题 消防监控系统中动态配置ODBC数据源的VC程序实现
范文

    卢志强

    摘要:面对客户提出的数据库中心需要由固定IP地址改为可动态修改的IP,以适应机房变更的需求,而且可能会在同一个应用程序中访问不同的数据库,作者在程序中自动完成这一工作的方法,快速满足了客户的需求。该文将详细介绍动态配置数据源的方法。

    关键词:ODBC 数据源;动态配置;VC

    中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2018)18-0063-01

    1 引言

    本人项目组开发了某消防监控系统,采用VC开发实现,使用固定配置的ODBC数据源,而系统交付后遇到客户需求更改,提出原设计的数据库中心需要由固定IP地址改为可动态修改的IP,以适应机房变更的需求,而且可能会在同一个应用程序中访问不同的数据库,因此采用一般的加载方法就有了无法克服的缺陷。如果能在程序中自动完成这一工作,将能快速满足客户的需求。那么该如何通过程序代码完成数据源的注册呢?本文将详细介绍动态配置数据源的方法。

    2 VC中加载数据源的具体实现

    在VC中注册ODBC数据源一般有两种方法:利用函数SQLConfigDataSource和修改注册表。本文重点介绍利用函数SQLConfigDataSource的方法。

    如果只是静态的配置ODBC数据源,即数据源各参数(数据源名称、服务器、数据库文件路径、数据库名等)是固定的,那么使用SQLConfigDataSource函数可以轻松的实现程序配置数据源,举例如下:

    if(SQLConfigDataSource(NULL, ODBC_ADD_DSN, "SQL Server",

    "DSN=EINet\0"

    "SERVER=192.168.1.100\0"

    "DATABASE=myEIfireDB\0"

    "Trusted_Connection=Yes\0")==1)

    AfxMessageBox("Success!");

    上面的代码也可以写成:

    if(SQLConfigDataSource(NULL, ODBC_ADD_DSN, "SQL Server", "DSN=EINet\0SERVER=192.168.1.100\0DATABASE=myEIfireDB\0Trusted_Connection=Yes")==1)

    AfxMessageBox("Success!");

    函數最后一个参数(lpszAttributes)为一连串的"KeyName = value"字符串,每两个KeyName值之间用""隔开,连续的两个引号,相当于连接符号,使用它们可以便于新代码排版,这比在行结尾处加连接符"\"更方便。lpszAttributes的具体设置,可以参考Windows系统目录下帮助文件odbcjtn.hlp主题目录标签中的“ODBC API函数改变|SQLConfigDataSource”条目。而尤其值得说明的是每个"KeyName = value"字符串都必须以"\0"结尾,这就造成了动态设定lpszAttributes的困难,先看这段代码:

    CString strSource;

    CString strIP = _T("192.168.1.100");

    strSource.Format("DSN=EINet\0SERVER=\"%s\"\0DATABASE=myEIfireDB\0Trusted_Connection=Yes",strIP);

    LPCSTR lpszAttributes = (LPCSTR)strSource;

    if(SQLConfigDataSource(NULL,ODBC_ADD_DSN,"SQL Server",lpszAttributes)==1)

    AfxMessageBox("Success!");

    else

    AfxMessageBox("Fail!");

    运行结果:Fail!

    单步调试观察变量变化:

    发现lpszAttributes仅包含"DSN=EINet"的信息,其他配置数据源的信息都丢失了,原因在于CString默认以"\0"作为字符串的结束标志,在强制类型转换时造成了数据丢失。

    解决办法为:使用编码转换,在堆栈中分配内存,创建一个char型数组,将lpszAttributes中的"\0"用"#"来表示,然后将数组中的字符赋给CString字符串,用CString的Replace方法再将"#"替换为"\0"。

    具体代码如下:

    BOOL AddDSN(CString strServerIP)

    {

    USES_CONVERSION;

    _TCHAR buffer[MAX_PATH] = {0};

    LPCTSTR lpstrServerIP = strServerIP;

    _stprintf(buffer, _T("DSN= eiSource #")_T("SERVER=%s#") _T("DATABASE=eiDB#")_T("Trusted_Connection=Yes#"),lpstrServerIP);

    CString strAttributes = buffer;

    int len = strAttributes.GetLength();

    strAttributes.Replace(_T('#'), _T('\0'));

    return SQLConfigDataSource(NULL, ODBC_ADD_DSN, "SQL Server", strAttributes.GetBuffer(len));

    }

    上面两个函数中用到的USES_CONVERSION是ATL中的一个宏定义。用于编码转换(用的比较多的是CString的LPCWSTR转换)。在ATL下使用要包含头文件atlconv.h,使用时一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放。如果在一个循环中,这个宏被反复调用几次,将不可避免的产生stackoverflow。为避免这种情况发生,同时减小代码量,在VC下可以更方便地直接使用下列代码:

    BOOL ConfigDSN(CString strServerIP){

    _TCHAR buffer[MAX_PATH] = {0};

    LPCTSTR lpstrServerIP = strServerIP;

    sprintf(buffer, _T("DSN= eiSource #")_T("SERVER=%s#") _T("DATABASE=eiDB#")_T("Trusted_Connection=Yes#"),lpstrServerIP);

    CString strAttributes = buffer;

    strAttributes.Replace(_T('#'), _T('\0'));

    return SQLConfigDataSource(NULL, ODBC_CONFIG_DSN, "SQL Server", strAttributes);

    }

    调用上述自定义函数:

    CString strServerIP = _T("192.168.1.100");

    if(AddDSN(strServerIP))

    AfxMessageBox("Success!");

    执行代码后结果:Success!

    可以看到,程序顺利地执行,成功配置好了数据源。

    3 结束语

    从以上分析和运行结果可以看出:利用函数SQLConfigDataSource和修改注册表,都可以实现动态修改数据源,尤其是可以实现多个数据源的切换,从而实现同一个应用程序中访问不同的数据库甚至通过IP地址切換实现访问同一数据源名的多个远程服务器。

随便看

 

科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。

 

Copyright © 2004-2023 puapp.net All Rights Reserved
更新时间:2024/12/22 17:31:20