当前位置:服务支持 >  软件文章 >  Sybase批量操作实现方法 高效数据处理技巧

Sybase批量操作实现方法 高效数据处理技巧

阅读数 8
点赞 0
article_banner

Sybase批量操作应该如何实现呢?下面就为您详细介绍Sybase批量操作的事项方法,如果您对Sybase批量操作方面感兴趣的话,不妨一看。

一、前言

在项目研发过程中,需要开发一个Sybase批量操作的动态链接库(DLL),以前的实现主要是程序中直接调用bcp.exe,这种方式由应用程序创建子进程,不好控制批量操作过程,失败跟踪难度比较大,因此想利用bcp.exe调用的函数来实现操作过程。本人通过分析bcp.exe程序,得到了批量操作的DB LIBRARY API函数,再查阅API函数的资料得以实现该动态链接库。

二、实现

批量操作动态链接库只实现了一个输出函数, 应用程序通过动态加载DLL,再获取函数地址,便可调用函数实现Sybase批量操作。

输出函数定义如下:

LIBBCP_API BOOL BCP_Transfer_2(const char *task, const char *step, const char *config, long *copiedrow);  
  • 1.

在动态链接库中定义了两个类:CInteriorGlobal和CSYBBCP。CInteriorGlobal完成全局的初始化操作,CSYBBCP实现数据库的批量操作。
在调用Sybase数据库的DB LIBRARY API函数进行数据库的相关操作时,首先需要调用dbsetversion函数设置版本信息,这个函数只能调用一次,如果再次调用则会报错。而类CSYBBCP在BCP_Transfer_2函数中动态创建和释放,如果在CSYBBCP中直接调用dbsetversion会导致多次调用出错。因此需要采用一种机制让dbsetversion只能调用一次,这里使用了设计模式中的SingleTom模式,SingleTom模式就是确保实例唯一,本人利用该类仅做一次实例化操作来初始化Sybase客户端版本信息。

下面是CInteriorGlobal的定义:

class CInteriorGlobal  
{  
public:  
static CInteriorGlobal *Instance();  
private:  
CInteriorGlobal();  
private:  
static CInteriorGlobal *_instance;  
};  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

CInteriorGlobal的实现,在构造函数中设置版本信息:

CInteriorGlobal::CInteriorGlobal()  
{  
dbsetversion(DBVERSION_100);  
}  
CInteriorGlobal    *CInteriorGlobal::_instance  = 0;  
CInteriorGlobal * CInteriorGlobal::Instance()  
{  
if(0 == _instance)  
_instance = new CInteriorGlobal;  
return _instance;  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

为了完成批量操作,定义类CSYBBCP,具体定义如下:

class CSYBBCP  
{  
public:  
CSYBBCP();  
~CSYBBCP();  
BOOL        DoConnect(int taskindex, int stepindex, char *server, char *database, char *username,  
char *password, char *charset, char *language);  
BOOL        DoQuery(char *sql, char **buf, int *rowcount, int *fieldcount);  
BOOL        DoUpdate(char *sql, char *database = NULL);  
BOOL        BCP_Connect(int taskindex, int stepindex, char *server, char *database,  
char *username, char *password, char *charset, char *language);  
BOOL        BCP_Transfer_db(char *sql, char *fldterminator, char *rowterminator, int direction,  
char *datafile, char *errfile, long *copiedrow);  
private:  
BOOL        m_isbcpout;  
int         m_stepindex;  
int         m_taskindex;  
char        m_viewname[MAX_STRING_NUM];  
char        m_database[MAX_STRING_NUM];  
DBPROCESS  *m_dbproc;  
private:  
int         GetTableFieldNums(char *table);  
BOOL        DoDisconnect();  
};  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

在类CSYBBCP中,主要是函数BCP_Transfer_db进行数据库大批量数据的导入和导出,要完成数据传输操作,需要如下几个步骤:

// 初始化:指定表明和数据文件  
if(bcp_init(m_dbproc, tablename, datafile, NULL, direction) == FAIL)  
{  
return FALSE;  
}  
// 设置批量操作的控制参数,这里设置的每批记录数  
if(bcp_control(m_dbproc, BCPBATCH, (DBINT) 1000) == FAIL)  
{  
return FALSE;  
}  
// 设置列数  
if(bcp_columns(m_dbproc, cCols) == FAIL)  
{  
return FALSE;  
}  
// 设置列格式  
for(ii = 1; ii < cCols; ii++)  
{  
if(bcp_colfmt(m_dbproc, ii, SYBCHAR, 0, -1, (UINT8 *) fldterminator, _strlen(fldterminator), ii) == FAIL)  
{  
return FALSE;  
}  
}  
if(bcp_colfmt(m_dbproc, ii, SYBCHAR, 0, -1, (UINT8 *) rowterminator, _strlen(rowterminator), ii) == FAIL)  
{  
return FALSE;  
}  
// 执行批量操作  
while(bcp_exec(m_dbproc, & cRows) == FAIL)  
{  
return FALSE;  
}  
// 批量操作结束  
retcode = bcp_done(m_dbproc);  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

在使用Sybase12.5客户端之前,程序未调用bcp_control函数,在执行bcp_exec函数时不是使用while,而是使用if判断,代码如下:

if(bcp_exec(m_dbproc, & cRows) == FAIL)  
{  
return FALSE;  
}  
  • 1.
  • 2.
  • 3.
  • 4.

程序能正常完成功能,当使用Sybase12.5客户端后,在执行时发现程序突然退出,异常处理也未能记录日志,后跟踪发现程序是在执行bcp_exec时退出,但是未能查出原因,咨询Sybase公司技术人员,也没能解决问题。后来在一次测试中偶然发现有时能导入数据,于是测试数据文件在什么情况下能导入,实验其临界点,多次测试后发现文件1000条记录为临界点,超过则出现问题。于是本人在程序中调用bcp_control函数,设置批量记录为1000,如果数据文件记录多于1000,则需要bcp_exec执行多次才能完成,所以采用while,而不是if,这样问题解决。

三、结束

在上面的论述中,还仅仅涉及DB LIBRARY,对于Sybase客户端编程,还有CT LIBRARY方式,目前CT已经支持导出,但不支持导入。

 


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空