Oracle

게시글 보기
작성자 유건데이타 등록일 2015-05-16
제목 EXPORT FILE 을 SAM FILE 로 변환하는 PROGRAM
PURPOSE
-------
Export 받은 dimp 파일로부터 Data를 Sam File로 만드는 방법에 대해
알아본다.

Explanation
-----------
다음 program 은 이처럼 이루어져 있다.

Function hirechary
main ---------- GetToken -----To_Number ----- Power
-----To_Char
-----To_Date
-------- MakeSam
-------- MakeControl

1)활용가능 분야( exp2sam )
1. Export dump file을 insert시 속도개선을 위하여 SQL*LOADER를 사용하고자
할 때
2. Export를 이용한 backup을 sam file로 가지고 있기를 원할 때.

2) exp2sam의 사용법
- SAM FILE로 generate하고자 원하는 export dump file을 exp2sam에 전달한다.
exp2sam expdat.dmp
- Export file안에 있는 table의 데이터들이 *.dat와 *.ctl파일로 생성된다.
- 만약 *.dat나 *.ctl 파일이 제대로 생성이 되지 않는다면, 그 machine은
byte wraping을 하는 machine이므로 source file에 #define WRAP 1의
remark를
풀어준후 compile하여 사용하면 된다.

3) 주 의 사 항
- exp2sam program은 export file을 sequential하게 읽으며 key word들과
data의 offset을 찾아 sam file을 생성하는 tool로서, export file의 header
부분에 문제가 있거나 table생성문 또는 다른 DDL관련 문장의 corruption에
관계없이 data를 축출한다.

- exp2sam은 SQL*LOADER를 위한 SAM FILE로 데이터를 생성하므로 LONG ROW나
LONG등의 DATA TYPE은 생성할 수 없다. 또한 현재의 VERSION은 export file을
open후 sequential하게 읽어 나가는 방식을 사용함으로써, export file에
long row가 들어가있을 경우 Program내에서 Token생성에 문제가 생겨
SAM FILE생성이 안될 수 있다.

4) program

#include
#include

/* #define DEBUG 1 */
#define WRAP 1
#define MAXLENGTH 1000
#define MAXCOLUMN 200
#define TRUE 1
#define FALSE 0

typedef enum { VARCHAR = 1, NUMBER = 2, DATE = 12 , CHAR = 96 }
DataType ;

FILE fp , out , *cont ;
int Colcnt = -1 ;
struct ColumnDef {
unsigned short Type ;
unsigned short Len ;
} Column [ MAXCOLUMN ] ;
char ControlColumn[MAXCOLUMN][MAXLENGTH] ;

void MakeSam() ;
int GetToken ( char *Token ) ;
void To_Char( unsigned short ValLength );
void To_Date( unsigned short ValLength ) ;
void To_Number ( unsigned short ValLength );
void MakeControl( char OutFile , char TableName );
int Power ( int Base , int Exponent );

void main( int argc , char *argv[] )
{
char Token [ MAXLENGTH ] ;
char OutFile [ 50 ] ;
char FileName [ 50 ] ;
char TableName [ 50 ] ;
int i , cnt ;

if ( argc < 2 ) {
printf("\nUsage : exp2sam expdat.dmp \n");
exit(1) ;
}

strcpy( FileName , argv[1] );

if((fp = fopen( FileName,"r")) == NULL ) {
/* Open Export dump file */
printf("Can not open file");
exit(1);
}

while( GetToken( Token ) != FALSE ) {
if ( strcmp ( Token , "INSERT" ) == 0 ) {
/* INSERT Statement */
for ( i = 0 ; i < 3 ; i++ )
if ( GetToken ( Token ) == FALSE ) {
/* Skip INTO and Get TAB */
printf("Unhandled exception!!!\n") ;
exit(1) ;
}
strcpy( OutFile , Token );

strcpy(TableName , OutFile );
strcat(OutFile,".ctl");
/* Make control file name */

if ((cont = fopen ( OutFile , "w")) == NULL) {
printf("Can not create control file %s\n", OutFile );
exit(1) ;
}

strcpy(OutFile , TableName );
strcat(OutFile , ".dat");
/* Make outfile name */

if ((out = fopen ( OutFile , "w")) == NULL) {
printf("Can not create file %s\n", OutFile ) ;
exit(1) ;
}

cnt = 0 ;
/***************************************/
/* get Last ')' which is at the end of */
/* INSERT (a ..) values (..) */
/* this is because cnt must be 2 */
/***************************************/
while ( GetToken( Token ) == TRUE ) {
if ( strcmp ( Token , ")" ) == 0 ) cnt++ ;
if ( cnt == 0 ) {
if( strcmp(Token , "(" ) == 0 || strcmp(Token,"")
== 0);
else {
/* Remove "" ex) "Col" -> Col */
strcpy( ControlColumn[ ++Colcnt ] , Token ) ;
}
}
if ( cnt == 2 ) {
MakeSam() ;
MakeControl( OutFile , TableName );
Colcnt = -1 ;
}
if ( cnt == 2 ) break ;
}
fclose(out);
fclose(cont);
} /* Enf of if */
} /* End of while-Loop */
fclose(fp);
}

void MakeControl( char OutFile , char TableName )
{
int i ;

fprintf( cont , "LOAD DATA\n" );
fprintf( cont , "INFILE %s\n", OutFile );
fprintf( cont , "INTO TABLE %s\n", TableName );
fprintf( cont , "FIELDS TERMINATED BY ','\n" );
fprintf( cont , "ENCLOSED BY '\"'\n" );
fprintf( cont , "(\n" );
for ( i = 0 ; i <= Colcnt ; i++ )
{
if( Column.Type == 12 )
if ( i == Colcnt )
fprintf( cont , \
"%s DATE \"YYYY-MM-DD HH24:MI:SS\"\n", ControlColumn[i]);
else
fprintf( cont , \
"%s DATE \"YYYY-MM-DD HH24:MI:SS\",\n", ControlColumn[i]);
else
if ( i == Colcnt )
fprintf( cont , "%s\n", ControlColumn[i] );
else
fprintf( cont , "%s,\n", ControlColumn[i] );
}
fprintf( cont , ")\n" );

}


int GetToken ( char *Token )
{
char Element ;
int i ;

i = 0 ;
while((Element = getc( fp )) != EOF ) {

switch ( Element ) {
case ')' : strcpy( Token , ")" );
return TRUE ;
case '(' : strcpy( Token , "(" );
return TRUE ;
case ',' :
case ' ' :
case '"' :
case '\r':
case '\n': Token [ i ] = '\0' ;
return TRUE ;
default :
if ( i == ( MAXLENGTH - 1 )) return FALSE ;
Token [ i++ ] = Element ; /* Make Token */
break;
};
};

return FALSE ;
}

void Wrap( unsigned short *wrapdata )
{
unsigned short high , row ;

high = row = *wrapdata ;

#ifdef DEBUG
printf("BEFORE SHIFT\n");
printf("wrap => %x\n" , *wrapdata);
#endif

high <<= 8 ;
row >>= 8 ;

high &= 0xff00 ;
row &= 0x00ff ;
#ifdef DEBUG
printf("AFTER SHIFT\n");
printf("high => %x\n" , high);
printf("row => %x\n" , row);
#endif

*wrapdata = high | row ;
#ifdef DEBUG
printf("RESULT\n");
printf("size of wrap => %d \t wrapdata => %x\n\n" , sizeof(*wrapdata),*wrapdata);
#endif
}

void MakeSam()
{
char dummy ;
int i ;
unsigned short NoCol , ValLength ;

/******************/
/* Column headers */
/******************/
dummy = getc( fp ); /* To get Catrige return */

fread( &NoCol, 2 , 1 , fp ) ;
#ifdef WRAP
Wrap( &NoCol );
#endif

#ifdef DEBUG
printf("No of Column -> %x " , NoCol );
scanf("PAUSE ---> %c",&dummy );
#endif

for ( i = 0 ; i < NoCol ; i++ ) { /* Perform for each column */
fread( &Column[i].Type , 2 , 1 , fp );
fread( &Column[i].Len , 2 , 1 , fp );
#ifdef WRAP
Wrap( &Column[i].Type );
Wrap( &Column[i].Len );
#endif

#ifdef DEBUG
printf("Type -> %d\tLength -> %d\n", Column[i].Type, Column[i].Len );
#endif
}

while ( 1 ) {
for ( i = 0 ; i < NoCol ; i++ ) {
fread ( &ValLength , 2 , 1 , fp );
#ifdef WRAP
Wrap( &ValLength );
#endif
if ( ValLength == 0xffff ) return ;
/* 0xfffe End of data */

switch ( Column[i].Type ) { /* Check Data type */
case NUMBER : /* To Interprite Number type data */
To_Number( ValLength ) ;
break ;

case DATE : /* To Interprite Date type data */
To_Date( ValLength );
break ;

case VARCHAR :
/* To Interprite VARCHAR, CHAR type data */
case CHAR :
To_Char( ValLength );
break ;
default : return ; /* for unknow Data type */
}
if ( i < (NoCol -1)) fprintf( out , ",");
/* Column seporator */
} /* End of for Loop */
fprintf( out , "\n");
} /* End of While Loop */
}

void To_Number ( unsigned short ValLength )
{
char Value ;
int Sign , Exponent , j ;
long int Mantissa = 0, Result;

if ( ValLength == 0xfffe ) fprintf( out , "\"\"" );
else {
Value = getc( fp ) ;
if ( (Value & 0x80 ) == 0x80 ) Sign = 1 ; /* Positive */
else Sign = 0 ; /* Negative */

Exponent = ( Value & 0x7f ) - 64 ; /* Exponent */

for( j = 0 ; j < ValLength - 1 ; j++ ) { /* Mantissa */
Value = getc( fp );
Mantissa = (Mantissa + ((Value - 1) * Power(100,
(( Exponent - 1 ) - j ))));
}

Result = (Sign == 1)? Mantissa : -1 * Mantissa ;
fprintf(out, "\"%d\"", Result );
}
}

int Power ( int Base , int Exponent )
{
int i , pow = 1 ;
for ( i = 1 ; i <= Exponent ; i++ ) pow = Base * pow ;
return pow ;
}

void To_Date( unsigned short ValLength )
{
char Value ;
int j ;

if ( ValLength == 0xfffe ) fprintf ( out , "\"\"" );
else
for( j = 0 ; j < ValLength ; j++ ) {
Value = getc( fp );
switch ( j )
{
case 0 : fprintf(out,"\"%d", Value - 100 );
break ;
case 1 : fprintf(out,"%d-", Value - 100 );
break ;
case 2 : fprintf(out,"%d-", Value );
break ;
case 3 : fprintf(out,"%d ", Value );
break ;
case 4 :
case 5 : fprintf(out,"%d:", Value - 1 );
break ;
default : fprintf(out,"%d\"", Value -1 );
break ;
}
}
}


void To_Char( unsigned short ValLength )
{
int j ;
char Value ;

if ( ValLength == 0xfffe ) fprintf ( out , "\"\"" );
else
{
fprintf( out , "\"" );
for( j = 0 ; j < ValLength ; j++ ) {
Value = getc( fp );
fprintf( out , "%c", Value );
}
fprintf( out , "\"" );
}
}

.
Comment
등록된 코멘트가 없습니다.