亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Oracle > 正文

PROC++批量導入導出ORACLE數據庫表

2024-08-29 13:49:26
字體:
來源:轉載
供稿:網友

  
最近在開發一個項目中,為了解決數據庫IO瓶頸,不得不把數據庫中的數據導出為文本文件。文本傳到客戶端后又要導入到數據庫。本人用C++Builder嵌入PROC++寫了一個導入導出的DLL。假如對你有用深感榮幸!具體內容如下:

 

一、預備工作

計算機環境:Win 2000 PRO,Oracle 9i,C++ Builder 5.5

引入必要的ORACLE內部函數:要用的函數在$(ORACEL_HOME)/bin qlora9.dll鏈接庫中。為了能在C++ Builder中使用,先得生成LIB:implib sqlora9.lib sqlora9.dll

 

二、源文件分析

//-------------------------------------------------------------------------

//加入必要的頭文件

#include<vcl.h> #include<windows.h> #include<stdio.h> #include<stdlib.h> #include<string.h>

#include<time.h> #include<math.h> #include<fcntl.h> #include<io.h> #include<sys tat.h>

//說明DLL的輸出函數

extern "C" _declspec(dlleXPort) int _stdcall ConnectDB(const char *Username,

                                const char *PassWord, const char *Dbname);

extern "C" _declspec(dllexport) int _stdcall ImportTxtfile(TList *LengthArray,

                                String *FieldArray, const char *TableName,

                                const char *FileName);

extern "C" _declspec(dllexport) int _stdcall ExportTxtfile(const char *Sql,

                                const char *FileName);

#pragma hdrstop

//----------------------------------------------------------------------------

#define MAX_ITEMS 20        //定義最大字段數

#define MAX_VNAME_LEN 30  //定義選擇表項最大長度

#define MAX_INAME_LEN 30  //定義指示器變量名字的最大長度

 

EXEC SQL INCLUDE sqlca;    //說明SQL通訊區

EXEC SQL INCLUDE oraca;    //說明ORACLE通訊區

EXEC SQL INCLUDE sqlda;    //說明SQL語句描述結構/*SQLDA結構體請查相關資料*/

 

EXEC ORACLE OPTION (ORACA = YES);

EXEC ORACLE OPTION (RELEASE_CURSOR = YES);

 

//說明ORACLE外部函數

extern "C" _declspec(dllimport) void _stdcall sqlclu(SQLDA*);

extern "C" _declspec(dllimport) void _stdcall sqlnul(short*, short*, int*);

extern "C" _declspec(dllimport) void _stdcall sqlprc(int*, int*, int*);

extern "C" _declspec(dllimport) strUCt SQLDA * _stdcall sqlald(int, unsigned int, unsigned int);

 

SQLDA *SelectUnit;  //定義選擇項描述

SQLDA *BindUnit;  //定義輸入項空間

//定義變量,以存放連接數據庫的參數

EXEC SQL BEGIN DECLARE SECTION;

    char User[20];//用戶名

    char Pwd[20];//密碼

    char DB[20];//數據庫服務名

EXEC SQL END DECLARE SECTION;

 

bool bConnect = false;//是否連接標志

#pragma hdrstop

 

#pragma argsused

//C++ Builder DLL的主函數

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)

{

        return 1;

}

 

/*---------------------------------------------------------------------------

    連接數據庫

---------------------------------------------------------------------------*/

int _stdcall ConnectDB(const char *Username, const char *Password,

                                   const char *Dbname)

{

  strcpy(User, Username);

  strcpy(Pwd, Password);

  strcpy(DB, Dbname);

 

  EXEC SQL CONNECT :User IDENTIFIED BY :Pwd USING :DB;

 

  if (sqlca.sqlcode < 0)

    return -1;

 

  bConnect = true;

  return 0;

}

/*---------------------------------------------------------------------------

導出文本函數

因為不確定SELECT語句的表及字段,所以我使用動態語句(ORACLE DYNAMIC SQL)的//第四種方式。
動態SQL方法四是在不確定SQL語句的選擇項與輸入項,且不知個數與數據類型的情況下使用的一種復雜程序設計技術。

---------------------------------------------------------------------------*/

int _stdcall ExportTxtfile(const char *Sql/*SQL選擇語句*/, const char FileName/*導出目標文本文件名*/)

{

  int null_ok, precision, scale;

 

  int handle;

 

  if ((handle = open(FileName, O_CREATO_TEXTO_APPENDO_RDWR, S_IREADS_IWRITE)) == -1)

  {

    //文件打開出錯

    return -1;

  }

//定義變量,以存放SQL語句

  EXEC SQL BEGIN DECLARE SECTION;

    char sqlstr[256];

  EXEC SQL END DECLARE SECTION;

 

  //檢查是否連接數據庫

  if (bConnect == false) return -2;

 

  strcpy(sqlstr/*.arr*/, Sql);

  //  sqlstr.len = strlen(sql);

 

  //給描述區分配空間 

  if ((SelectUnit = sqlald(MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN)) == (SQLDA *)NULL)

  {

    //空間分配失敗

    return -3;

  }

 

  if ((BindUnit = sqlald(MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN)) == (SQLDA *)NULL)

  {

    //空間分配失敗

    return -3;

  }

  //給查詢返回值存儲區分配空間

  SelectUnit->N = MAX_ITEMS;

  for (int i=0; i < MAX_ITEMS; i++)

  {

    BindUnit->I[i] = (short *)malloc(sizeof(short *));

    BindUnit->V[i] = (char *)malloc(MAX_VNAME_LEN);

  }

  for (int i=0; i < MAX_ITEMS; i++)

  {

    SelectUnit->I[i] = (short *)malloc(sizeof(short *));

    SelectUnit->V[i] = (char *)malloc(MAX_VNAME_LEN);

  }

 

  EXEC SQL WHENEVER SQLERROR GOTO sqlerr;//DO sql_error("導出出錯");

//設置SQL語句

  EXEC SQL PREPARE SQLSA FROM :sqlstr;

  EXEC SQL DECLARE Cursorbase CURSOR FOR SQLSA;

 

  //輸入描述處理

  BindUnit->N = MAX_ITEMS;

  EXEC SQL DESCRIBE BIND VARIABLES for SQLSA INTO BindUnit;

 

  if (BindUnit->F < 0)

  {

    return -4;

    //輸入項過多

  }

  BindUnit->N = BindUnit->F;

  //打開光標

  EXEC SQL OPEN Cursorbase USING DESCRipTOR BindUnit;

 

  //選擇項處理

  EXEC SQL DESCRIBE SELECT LIST for SQLSA INTO SelectUnit;

 

  if (SelectUnit->F < 0)

  {

    return -4;

    //選擇表項過多

  }

  SelectUnit->N = SelectUnit->F;

//因為所有格式,類型都是不確定的,所以要得到正確的返回值就要處理格式

  for (int i=0; i < SelectUnit->F; i++)

  {

    sqlnul(&(SelectUnit->T[i]), &(SelectUnit->T[i]), &null_ok);

    switch (SelectUnit->T[i])

    {

           case 1://CHAR

                break;

           case 2://NUMBER

                sqlprc(&(SelectUnit->L[i]), &precision, &scale);

                if (precision == 0)

                  precision = 40;

                SelectUnit->L[i] = precision + 2;

                break;

        case 8://LONG

             SelectUnit->L[i] = 240;

             break;

        case 11://ROWID

             SelectUnit->L[i] = 18;

             break;

        case 12://DATE

             SelectUnit->L[i] = 9;

             break;

        case 23://RAW

             break;

        case 24://LONGRAW

             SelectUnit->L[i] = 240;

             break;

     }

 

     SelectUnit->V[i] = (char *)realloc(SelectUnit->V[i], SelectUnit->L[i]+1);

 

     SelectUnit->T[i] = 1;//把所有類型轉換為字符型

  }

 

  EXEC SQL WHENEVER NOT FOUND goto EndFor;

 

  for (;;)

  {

    EXEC SQL FETCH Cursorbase USING DESCRIPTOR SelectUnit;

 

    //輸出各字段

    for (int i=0; i < SelectUnit->F; i++)

    {

      char buffer[256];

 

      if (i != SelectUnit->F-1)

        sprintf(buffer, "%s", SelectUnit->V[i]);

      else sprintf(buffer, "%s/r/n", SelectUnit->V[i]);

 

      int length = strlen(buffer);

 

      if (write(handle, buffer, length) != length)

      {

        return -5;

        //寫文件失敗 exit(1);

      }

    }

 

  }

 

EndFor:

 

  close(handle);

 

  for (int i=0; i < MAX_ITEMS; i++)

  {

    if (SelectUnit->V[i] != (char *)NULL)

      free(SelectUnit->V[i]);

 

    free(SelectUnit->I[i]);

  }

 

  for (int j=0; j < MAX_ITEMS; j++)

  {

    if (BindUnit->V[j] != (char *)NULL)

      free(BindUnit->V[j]);

 

    free(BindUnit->I[j]);

  }

 

  sqlclu(SelectUnit);

  sqlclu(BindUnit);

 

  EXEC SQL CLOSE Cursorbase;

 

  return 0;

 

sqlerr:

  return -6;

}

 

/*----------------------------------------------------------------------------

導入文本

為了批量導入,在此我調用的sqlldr工具

首先生成SQL*Loader控制文件,后運行sqlldr

----------------------------------------------------------------------------*/

int _stdcall ImportTxtfile(TList LengthArray/*導入文本的字段長度鏈表*/,

String *FieldArray/*數據庫表的了段名數組*/, const char TableName/*導入的目標表*/, const char FileName/*導入的源文本文件*/)

{

  //產生SQL*Loader控制文件

  FILE *fout, *fp;

  char Execommand[256];

 

  char sqlload[] = "./ qlload.ctl";

 

  //檢查是否連接數據庫

  if (bConnect == false) return -2;

 

  if ((fout=fopen(sqlload, "w")) == NULL)

  {

    //建立控制文件出錯

    return -1 ;

  }

 

  fprintf(fout, "LOAD DATA/n");

  fprintf(fout, "INFILE '%s'/n", FileName);

  fprintf(fout, "APPEND INTO TABLE %s (/n", TableName);

 

  int iStart = 1;

  for(int i=0; i < LengthArray->Count; i++)

  {

    fprintf(fout, "%11s POSITION(%d:%d)", FieldArray[i], iStart, *(int*)LengthArray->Items[i]+iStart-1);

    iStart += *(int*)LengthArray->Items[i];

    fprintf(fout, " CHAR");

 

    if(i < LengthArray->Count-1)

      fprintf(fout, ",/n");

  }

  fprintf(fout, ")/n");

  fclose(fout);

 

  sprintf(Execommand, "sqlldr.exe userid=%s/%s@%s control=%s",

                      User, Pwd, DB, sqlload);

 

  if (system(Execommand) == -1)

  {

    //SQL*Loader執行錯誤

    return -1;

  }

 

  return 0 ;

}

 

 

//----------------------------------------------------------------------------

三、編譯

用ORACLE的PROC預編譯器預編后,放入C++ Builder中聯編。
聯編時需加入前面生成的sqlora9.lib。聯編時還要注重,所有PROC生成的ORACLE內部函數調用都要說明為extern "C" _declspec(dllexport) TYPE _stdcall類型。

 

水平有限還請見諒?。?!請多多指點。QQ:5005647

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久7777婷婷| 欧美激情免费在线| 最新91在线视频| 亚洲一区二区三区xxx视频| 菠萝蜜影院一区二区免费| 国产精品免费一区豆花| 亚洲免费精彩视频| 国产精品久久久久久久av电影| 国产又爽又黄的激情精品视频| 国产在线久久久| 国产精品人成电影在线观看| 97久久久免费福利网址| 中文字幕精品—区二区| 久久夜色精品国产欧美乱| 一区二区成人av| 亚州国产精品久久久| 欧美二区在线播放| 欧美性xxxxx| 红桃视频成人在线观看| 亚洲精品久久7777777| 亚洲第一区中文99精品| 欧美激情中文字幕乱码免费| 欧美一区二区色| 精品偷拍一区二区三区在线看| 国产视频亚洲视频| 色婷婷亚洲mv天堂mv在影片| 国产精品主播视频| 国产精品一二区| 日韩精品免费视频| 日韩免费电影在线观看| 97视频免费观看| 日韩天堂在线视频| 欧美激情久久久久久| 日本亚洲精品在线观看| 欧美麻豆久久久久久中文| 欧美成人午夜剧场免费观看| 久久伊人精品天天| yw.139尤物在线精品视频| 黄网站色欧美视频| 2018中文字幕一区二区三区| 精品国产鲁一鲁一区二区张丽| 日韩三级成人av网| 亚洲三级免费看| 日韩在线视频播放| 亚洲欧洲日产国产网站| 欧美日韩国产成人在线| 亚洲人午夜精品免费| 国产成人一区二区在线| 这里精品视频免费| 亚洲综合最新在线| 久久久精品国产一区二区| 欧美极品少妇xxxxⅹ裸体艺术| 在线观看欧美成人| 日韩极品精品视频免费观看| 国产精品久久久久久久久久小说| 国产成人精品在线观看| 午夜精品久久久久久久久久久久| 久久久极品av| 久久精品视频导航| 亚洲精品成人久久久| 久久久久久久97| 欧美激情精品久久久| 91禁国产网站| 日韩精品在线私人| 国产精品香蕉av| 亚洲第一区在线观看| 国产激情综合五月久久| 97热在线精品视频在线观看| 日韩中文字幕视频| 久久夜色精品国产欧美乱| 国产第一区电影| 亚洲热线99精品视频| 在线亚洲男人天堂| 国内精品400部情侣激情| 亚洲一区二区精品| 精品视频www| 久久久国产视频| 亚洲第一天堂av| 日韩av中文字幕在线免费观看| 91久久精品国产91久久| 97在线视频免费| 在线观看日韩www视频免费| 91沈先生在线观看| 国产精品直播网红| 日韩在线中文字| 久久久久久久久国产| 国产午夜精品一区二区三区| 亚洲综合在线做性| 日韩小视频网址| 日韩视频免费在线观看| 精品爽片免费看久久| 亚洲午夜性刺激影院| 国产一区二区在线免费| 久色乳综合思思在线视频| 欧美极品欧美精品欧美视频| 欧美激情喷水视频| 欧美刺激性大交免费视频| 色偷偷av亚洲男人的天堂| 亚洲男人天堂手机在线| 丝袜情趣国产精品| 欧美国产一区二区三区| 日韩小视频网址| 68精品久久久久久欧美| 91免费视频国产| 午夜精品一区二区三区av| 中文字幕精品网| 久久久国产91| 欧美午夜视频在线观看| 91亚洲人电影| 欧美性猛交xxxx乱大交蜜桃| 亚洲国产精品va在看黑人| 欧美黑人xxxx| 久久久久久有精品国产| 啊v视频在线一区二区三区| 亚洲欧洲日韩国产| 欧美激情亚洲一区| 国a精品视频大全| 中文字幕日韩精品有码视频| 亚洲精品久久久久国产| 日韩精品中文字幕在线播放| 欧美视频在线免费看| 91香蕉国产在线观看| 国产精品美女久久久久久免费| 粉嫩av一区二区三区免费野| 亚洲欧美一区二区三区四区| 亚洲电影免费观看| 日韩激情第一页| 欧美成人精品在线观看| 国产美女精品免费电影| 亚洲a在线观看| 欧美一乱一性一交一视频| 51色欧美片视频在线观看| 在线日韩日本国产亚洲| 亚洲成成品网站| 欧美成人免费全部| 国自产精品手机在线观看视频| 日韩欧美综合在线视频| 青青草原一区二区| 情事1991在线| 91日韩在线播放| 国产在线观看91精品一区| www.xxxx欧美| 亚洲精品videossex少妇| 91精品啪aⅴ在线观看国产| 久久免费视频在线观看| 欧美激情在线视频二区| 国产精品综合久久久| 亚洲国产日韩欧美在线图片| 日韩在线欧美在线国产在线| 亚洲第一区第二区| 国产精品久久二区| 精品亚洲国产视频| 成人午夜在线观看| 日韩欧美999| 九九精品在线播放| 国产精品网红直播| 国产亚洲欧美日韩美女| 亚洲无av在线中文字幕| 国产精品视频色| 久久久国产视频91| 九九热r在线视频精品| 欧美亚洲视频在线看网址| 日韩网站在线观看| 欧美黄色免费网站|