Proc ++ Batch Import Export Oracle Database Table

zhaozj2021-02-16  53

Recently, in a project, in order to solve the database IO bottleneck, you have to export data in the database into text files. The text is passed to the client and imports to the database. I use C Builder to embed a import-exported DLL with C Builder. If you are useful for you! The details are as follows:

First, ready to work

Computer environment: Win 2000 Pro, Oracle 9i, C Builder 5.5

Introducing the necessary Oracle internal functions: The function you want is in the $ (ORACEL_HOME) /bin/sqlora9.dll link library. In order to be used in C Builder, first you build lib: IMPLIB SQLORA9.LIB SQLORA9.DLL

Second, the source file analysis

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

// Add the necessary header file

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

/ / Describe the output function of the 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 the maximum number of fields

#define max_vname_len 30 // Define the maximum length of the selection entry

#define max_INAME_LEN 30 // Defines the maximum length of the indicator variable name

EXEC SQL include Sqlca; // Description SQL communication area

EXEC SQL include ORACA; / / Description Oracle Communication Area

EXEC SQL include Sqlda; // Description SQL statement description structure / * SQLDA structure please check the relevant information * /

EXEC ORACLE OPTION (ORACA = YES);

EXEC ORACLE OPTION (Release_Cursor = YES);

// Describe the Oracle external function

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; // Definition selection description

Sqlda * bindunit; / / Define Enter Int Space

/ / Define the variable to store the parameters of the connection database

EXEC SQL Begin Declare Section;

Char user [20]; // user name

CHAR PWD [20]; // password

Char DB [20]; // Database Service Name

Exec SQL End Declare Section;

BOOL BCONNECT = false; // Whether to join the sign

#pragma HDRSTOP

#pragma argsused

// C Builder DLL main function

Bool WinApi Dllmain (Hinstance Hinstdll, DWord Fwdreason, LPVOID LPVRESERVED)

{

Return 1;

}

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

Connect to the database

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

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;

}

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

Export text function

Since the table and field of the SELECT statement is not determined, I use the dynamic statement (Oracle Dynamic SQL) // fourth way. Dynamic SQL Method 4 is a complex program design technology that does not determine the selection item and input items of the SQL statement, and unknown with a number of complex programming techniques used in the case of data type.

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

INT _STDCALL EXPORTTXTFILE (const char * sql / * sql selection statement * /, const char filename / * export target text file name * /)

{

INT NULL_OK, Precision, Scale;

INT HANDLE;

IF ((",",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

{

// File open error

Return -1;

}

/ / Define the variable to store SQL statements

EXEC SQL Begin Declare Section;

Char sqlstr [256];

Exec SQL End Declare Section;

/ / Check if you connect the database

IF (bconnect == false) return -2;

STRCPY (SQLSTR / *. Arr * /, SQL);

// SQLSTR.LEN = Strlen (SQL); // Assign space to the description area

IF ((SelectUnit = SQLALD (MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN) == (SQLDA *) NULL)

{

/ / Spatial distribution failed

Return -3;

}

IF (BindUnit = SQLALD (MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN) == (SQLDA *) NULL)

{

/ / Spatial distribution failed

Return -3;

}

// Give the query return value storage area allocation space

SelectUnit-> n = max_items;

For (int i = 0; i

{

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

Bindunit-> V [I] = (char *) malloc (max_vname_len);

}

For (int i = 0; i

{

SelectUnit-> i [i] = (short *) Malloc (SIZEOF (Short *));

SelectUnit-> v [I] = (char *) malloc (max_vname_len);

}

EXEC SQL WHENEVER SQLEC GOTO SQLERR; // DO SQL_ERROR ("Export Error");

/ / Set SQL statement

Exec SQL Prepare Sqlsa from: SQLSTR;

EXEC SQL DECLARE CURSORBASE CURSOR for SQLSA;

/ / Input Description Processing

BindUnit-> n = max_items;

Exec SQL Describe Bind Variables for Sqlsa Into Bindunit;

IF (BindUnit-> f <0)

{

Return-4;

// Input items too much

}

BindUnit-> n = bindunit-> f;

// Open the cursor

Exec SQL Open CursorBase Using Descriptor Bindunit;

// Select item processing

Exec SQL Describe Select List for Sqlsa Into SelectUnit;

IF (selectUnit-> f <0)

{

Return-4;

// Select too much item

}

SelectUnit-> n = selectUnit-> f;

// Because all formats, types are uncertain, so you have to get the correct return value.

For (int i = 0; i f; i )

{

SQLNUL (& (SelectUnit-> T [I]), & (SelectUnit-> T [I]), & null_ok);

Switch (SelectUnit-> T [I])

{

Case 1: // charr

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; // Convert all types to characteristics

}

EXEC SQL WHENEVER NOT FOUND GOTO ENDFOR;

For (;;)

{

EXEC SQL FETCH CURSORBASE Using Descriptor SelectUnit;

/ / Output of each field

For (int i = 0; i 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;

// Write file failed exit (1);

}

}

}

ENDFOR:

Close (Handle);

For (int i = 0; i

{

IF (selectUnit-> v [i]! = (char *) NULL)

Free (SelectUnit-> V [I]);

Free (SelectUnit-> i [i]);

}

For (int J = 0; 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;

}

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

Import text

For mass import, here I call SQLDR tools

First become a SQL * LoAder control file, then run SQLLDR

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

INT _STDCALL IMPORTTXTFILE (TLIST Length "imported field length chain table * /,

String * FieldArray / * Database table's Segment name * /, const char Tablename / * Import Target Table * /, Const Char FileName / * Import Source text file * /)

{

// Generate SQL * Loader Control File

File * fout, * fp;

Char Execommand [256];

Char Sqlload [] = ".//sqlload.ctl"// Check if the database is connected

IF (bconnect == false) return -2;

IF ((Fout = FOPEN)) == null)

{

// Establish a control file error

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 count; i )

{

FPRINTF (Fout, "% 11S Position (% D:% D)", FieldArray [i], iStart, * (int *) LengthTharray-> items [i] iStart-1);

iStart = * (int *) LengthTharray-> items [i];

FPRINTF (Fout, "char");

IF (i count-1)

FPRINTF (fout, ", / n");

}

FPRINTF (Fout, ") / N");

Fclose (fout);

Sprintf (execommand, "sqlldr.exe userid =% s /% s @% s constroL =% s",

User, PWD, DB, SQLLOAD;

IF (System (Execommand) == -1)

{

// SQL * Loader Execute Error

Return -1;

}

Return 0;

}

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

Third, compile

After pre-edoing the Oracle's Proc Precipcherator, add C Builder. The coupled sqlora9.lib is required to join the previously generated. Pay attention to the connection, all the Oracle internal function calls generated by all PROCs must be described as the extern "c" _declspec (dllexport) Type_stdcall type.

I will forgive me! ! ! Please have a point. QQ: 5005647

转载请注明原文地址:https://www.9cbs.com/read-24184.html

New Post(0)