TECH
QUESTION
자주하는 질문답변 입니다.
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 | |||
---|---|---|---|
등록된 코멘트가 없습니다. |