Sybase批量操作的实现

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

一、前言

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

二、实现

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

输出函数定义如下:

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

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

下面是CInteriorGlobal的定义:

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

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

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

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

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

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

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

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

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

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

三、结束

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

 

【编辑推荐】

设置SYBASE用户口令为空

深入探究SYBASE数据库日志

Sybase日期函数应用示例

Sybase建立索引的原则

Sybase分页显示存储过程

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/230498.html<

(0)
管理的头像管理
上一篇2025-04-19 06:30
下一篇 2025-04-19 06:31

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注