电脑技术学习

Sybase批量操作(BCP)的设计和实现

dn001

本文主要讲述了Sybase数据库批量操作(BCP)的设计和实现,以及在开发过程中的关键点,为后续开发者提供了技术基础

一、前言

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

二、实现

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

输出函数定义如下: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的定义:

class CInteriorGlobal

{

public:

static CInteriorGlobal *Instance();

private:

CInteriorGlobal();

private:

static CInteriorGlobal *_instance;

};

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

{

dbsetversion(DBVERSION_100);

}

CInteriorGlobal *CInteriorGlobal::_instance = 0;

CInteriorGlobal * CInteriorGlobal::Instance()

{

if(0 == _instance)

_instance = new CInteriorGlobal;

return _instance;

}

为了完成批量操作,定义类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();

};

标签: