日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Sybase批量操作的實(shí)現(xiàn)

Sybase批量操作應(yīng)該如何實(shí)現(xiàn)呢?下面就為您詳細(xì)介紹Sybase批量操作的事項(xiàng)方法,如果您對(duì)Sybase批量操作方面感興趣的話,不妨一看。

創(chuàng)新互聯(lián)建站是一家專業(yè)提供德惠企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、H5建站、小程序制作等業(yè)務(wù)。10年已為德惠眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

一、前言

在項(xiàng)目研發(fā)過(guò)程中,需要開(kāi)發(fā)一個(gè)Sybase批量操作的動(dòng)態(tài)鏈接庫(kù)(DLL),以前的實(shí)現(xiàn)主要是程序中直接調(diào)用bcp.exe,這種方式由應(yīng)用程序創(chuàng)建子進(jìn)程,不好控制批量操作過(guò)程,失敗跟蹤難度比較大,因此想利用bcp.exe調(diào)用的函數(shù)來(lái)實(shí)現(xiàn)操作過(guò)程。本人通過(guò)分析bcp.exe程序,得到了批量操作的DB LIBRARY API函數(shù),再查閱API函數(shù)的資料得以實(shí)現(xiàn)該動(dòng)態(tài)鏈接庫(kù)。

二、實(shí)現(xiàn)

批量操作動(dòng)態(tài)鏈接庫(kù)只實(shí)現(xiàn)了一個(gè)輸出函數(shù), 應(yīng)用程序通過(guò)動(dòng)態(tài)加載DLL,再獲取函數(shù)地址,便可調(diào)用函數(shù)實(shí)現(xiàn)Sybase批量操作。

輸出函數(shù)定義如下:

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

在動(dòng)態(tài)鏈接庫(kù)中定義了兩個(gè)類:CInteriorGlobal和CSYBBCP。CInteriorGlobal完成全局的初始化操作,CSYBBCP實(shí)現(xiàn)數(shù)據(jù)庫(kù)的批量操作。
在調(diào)用Sybase數(shù)據(jù)庫(kù)的DB LIBRARY API函數(shù)進(jìn)行數(shù)據(jù)庫(kù)的相關(guān)操作時(shí),首先需要調(diào)用dbsetversion函數(shù)設(shè)置版本信息,這個(gè)函數(shù)只能調(diào)用一次,如果再次調(diào)用則會(huì)報(bào)錯(cuò)。而類CSYBBCP在BCP_Transfer_2函數(shù)中動(dòng)態(tài)創(chuàng)建和釋放,如果在CSYBBCP中直接調(diào)用dbsetversion會(huì)導(dǎo)致多次調(diào)用出錯(cuò)。因此需要采用一種機(jī)制讓dbsetversion只能調(diào)用一次,這里使用了設(shè)計(jì)模式中的SingleTom模式,SingleTom模式就是確保實(shí)例唯一,本人利用該類僅做一次實(shí)例化操作來(lái)初始化Sybase客戶端版本信息。

下面是CInteriorGlobal的定義:

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

CInteriorGlobal的實(shí)現(xiàn),在構(gòu)造函數(shù)中設(shè)置版本信息:

 
 
 
  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中,主要是函數(shù)BCP_Transfer_db進(jìn)行數(shù)據(jù)庫(kù)大批量數(shù)據(jù)的導(dǎo)入和導(dǎo)出,要完成數(shù)據(jù)傳輸操作,需要如下幾個(gè)步驟:

 
 
 
  1. // 初始化:指定表明和數(shù)據(jù)文件
  2. if(bcp_init(m_dbproc, tablename, datafile, NULL, direction) == FAIL)
  3. {
  4. return FALSE;
  5. }
  6. // 設(shè)置批量操作的控制參數(shù),這里設(shè)置的每批記錄數(shù)
  7. if(bcp_control(m_dbproc, BCPBATCH, (DBINT) 1000) == FAIL)
  8. {
  9. return FALSE;
  10. }
  11. // 設(shè)置列數(shù)
  12. if(bcp_columns(m_dbproc, cCols) == FAIL)
  13. {
  14. return FALSE;
  15. }
  16. // 設(shè)置列格式
  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. // 執(zhí)行批量操作
  29. while(bcp_exec(m_dbproc, & cRows) == FAIL)
  30. {
  31. return FALSE;
  32. }
  33. // 批量操作結(jié)束
  34. retcode = bcp_done(m_dbproc);

在使用Sybase12.5客戶端之前,程序未調(diào)用bcp_control函數(shù),在執(zhí)行bcp_exec函數(shù)時(shí)不是使用while,而是使用if判斷,代碼如下:

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

程序能正常完成功能,當(dāng)使用Sybase12.5客戶端后,在執(zhí)行時(shí)發(fā)現(xiàn)程序突然退出,異常處理也未能記錄日志,后跟蹤發(fā)現(xiàn)程序是在執(zhí)行bcp_exec時(shí)退出,但是未能查出原因,咨詢Sybase公司技術(shù)人員,也沒(méi)能解決問(wèn)題。后來(lái)在一次測(cè)試中偶然發(fā)現(xiàn)有時(shí)能導(dǎo)入數(shù)據(jù),于是測(cè)試數(shù)據(jù)文件在什么情況下能導(dǎo)入,實(shí)驗(yàn)其臨界點(diǎn),多次測(cè)試后發(fā)現(xiàn)文件1000條記錄為臨界點(diǎn),超過(guò)則出現(xiàn)問(wèn)題。于是本人在程序中調(diào)用bcp_control函數(shù),設(shè)置批量記錄為1000,如果數(shù)據(jù)文件記錄多于1000,則需要bcp_exec執(zhí)行多次才能完成,所以采用while,而不是if,這樣問(wèn)題解決。

三、結(jié)束

在上面的論述中,還僅僅涉及DB LIBRARY,對(duì)于Sybase客戶端編程,還有CT LIBRARY方式,目前CT已經(jīng)支持導(dǎo)出,但不支持導(dǎo)入。


當(dāng)前文章:Sybase批量操作的實(shí)現(xiàn)
文章起源:http://www.dlmjj.cn/article/djceses.html