zoukankan      html  css  js  c++  java
  • ETL应用:使用Pro*C写入文件信息入库的方法

         ETL处理过程中,经常需要进行文件校验,如文件级校验、记录级校验,需要保存文件的基本信息,文件名、文件大小、数据日期等,使用Pro*C的一种方法如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <limits.h>
    #include <sqlda.h>
    #include <sqlcpr.h> 
    /*定义数据库连接信息*/
    #define USERNAME    "masaetl"
    #define PASSWORD    "masaetl"
    #define ORACLESID   "DWDB2"
    /*定义数据存放目录,这些目录是链接文件的目录*/
    char data_dir[5][64]={ "/ETL_FS/etlfs/interface/boss/input/day_full",
                         "/ETL_FS/etlfs/interface/boss/input/day_incr",
                         "/ETL_FS/etlfs/interface/boss/input/oth_full",
                         "/ETL_FS/etlfs/interface/boss/input/oth_incr",
                         "/ETL_FS/etlfs/interface/kf_data/link"
    };     
    /*定义处理日期,内部链接的静态变量*/
    static char filedate[9];
    /*调试代码时使用*/
    #ifndef DEBUG
    #define DEBUG   // 定义调试开关
    #endif
    /*SQL语句返回值定义*/
    /*定义返回值,成功为0,错误<0,警告>0  */
    #define SQLCODE   sqlca.sqlcode      
    /*SQL语句返回错误解释 */
    #define SQLERRMC  sqlca.sqlerrm.sqlerrmc     
    /*包含数据库信息*/
    EXEC SQL INCLUDE sqlca;
    EXEC SQL INCLUDE sqlda;
    /*SQL语句返回值定义*/
    /*定义返回值,成功为0,错误<0,警告>0*/
    #define SQLCODE   sqlca.sqlcode   
    /*SQL语句返回错误解释*/  
    #define SQLERRMC  sqlca.sqlerrm.sqlerrmc     
    void sqlerror();           /*处理SQL错误*/
    int ConnectDataBase();     /*链接数据库*/
    void DisConnectDataBase(); /*断开数据库连接*/
    char *getYestDate(char *szDate);   /*得到前一天的日期,格式"YYYYMMDD"*/
    char *getFileName(const char *szFilePath,char *szFileName); /*从字符串中得到文件名*/
    /**************************************
    *** 功能: 提取运行在数据库级报错信息
    *** 输入变量:
    *** 输出变量:
    ***************************************/
    void sqlerror()
    {
       /*为了避免错误处理时发生死循环,应给出此说明*/
       EXEC SQL WHENEVER SQLERROR CONTINUE;
       printf("
     Oracle error detected: ");
       printf("
    %s",SQLERRMC);  /*错误信息*/
       
       /*断开数据库链接*/
       EXEC SQL ROLLBACK WORK RELEASE;
       exit(1);
    }
    /**************************************
    *** 功能:  连接数据库
    *** 输入变量:
    *** 输出变量: -1 连接数据库失败 0 成功
    ***************************************/
    int ConnectDataBase()
    {
      EXEC SQL BEGIN DECLARE SECTION;
              char  username[8];
              char  password[11];
              char  oraclesid[7];
        EXEC SQL END DECLARE  SECTION;
        
      strcpy(username,USERNAME);  /*用户名*/
       //username.len=strlen(username.arr);
       
       strcpy(password,PASSWORD);  /*密码*/
       //password.len=strlen(password.arr);
       
       strcpy(oraclesid,ORACLESID);  /*Oralce SID*/
       //oraclesid.len=strlen(oraclesid.arr);
       
       /*链接数据库*/
       EXEC SQL CONNECT :username IDENTIFIED BY :password USING :oraclesid; 
       if( SQLCODE ) { 
        
         return -1;
        }
       return 0; 
    }
    /**************************************
    *** 功能:  断开数据库连接
    *** 输入变量:
    *** 输出变量: 
    ***************************************/
    void DisConnectDataBase()
    {
      /*断开连接*/
    EXEC SQL ROLLBACK WORK RELEASE;
      exit(0);
    }
    /***************************************
    **  功能 :    得到前一天的日期
    *** 输入变量:
    *** 输出变量: 
    ****************************************/
    char *getYestDate(char *szDate)
    {
       time_t yest;
       struct tm ptime={''};
       char szChar[5];
         
       //若输入的参数为空,默认提取系统前一天的日期
       if ( *szDate =='' ){
          
          yest=time(NULL)-(time_t)(60*60*24);
          strftime(szDate,9,"%Y%m%d",localtime(&yest));
           
          return szDate;
         }
       //提取年
       memset(szChar,0,sizeof(szChar));
       strncpy(szChar,szDate,4);
       ptime.tm_year=atoi(szChar)-1900;
         
       //提取月
       memset(szChar,0,sizeof(szChar));
       strncpy(szChar,szDate+4,2);
       ptime.tm_mon=atoi(szChar)-1;
         
       //提取日
       memset(szChar,0,sizeof(szChar));
       strncpy(szChar,szDate+6,2);
       ptime.tm_mday=atoi(szChar);
         
       yest=mktime(&ptime)-(time_t)(60*60*24);
       strftime(szDate,9,"%Y%m%d",localtime(&yest));
         
       return szDate;
    }
    /***************************************
    **  功能 :    从文件路径中得到文件名称(去掉前面的路径)
    *** 输入变量:文件路径
    *** 输出变量:文件名
    ****************************************/
    char *getFileName(const char *szFilePath,char *szFileName)
    {
        char *szPtr;
        
        const char separator='/';   /*定义分隔符*/
        szPtr=strrchr(szFilePath,separator);   /*查找最后一个子串*/
        
        if ( szPtr ){
         
           szFileName=szPtr+1;
         }
    #ifdef DEBUG
       printf("文件名称为: [%s]",szFileName);     
    #endif
        return szFileName;
    }
    /***************************************
    **  功能 :    主程序
    ****************************************/
    int main( void )
    {
    int i=0;
    char *szOrderId;
    char pFileName[128];
    char *filename;         //文件名
    char szDate[15];        //日期 "yyyymmddhh24miss"
    time_t  file_mtime;     //文件时间
    
    struct stat st;
    struct dirent *dirp;
    DIR    *pDirectory;
    
    /*定义数据库变量*/
    EXEC SQL BEGIN DECLARE SECTION;
          char    file_date[9];             //文件日期
          long    orderid;                  //序号(接口编号)
          char    file_name[30];            //文件名称
          long    file_size;                //文件大小
          char    file_create_date[15];     //文件最后修改的时间
    EXEC SQL END DECLARE SECTION;
    
    /*链接数据库*/
    if( ConnectDataBase()<0 ){
      
        printf("连接数据失败.
    ");
    }
    
    /*得到处理日期*/
    getYestDate(filedate);
    strcpy(file_date,filedate);
    #ifdef DEBUG
       printf("处理日期: [%s].
    ",file_date);     
    #endif
      /*删除当日已统计数据*/
       EXEC SQL DELETE FROM
              MASAETL.ETL_LINK_FILE WHERE FILEDATE=:file_date;
               
      /*处理执行SQL异常*/
       if ( 1403!=SQLCODE && 0!=SQLCODE ){
        
    #ifdef DEBUG
        printf("删除当日统计数据失败,原因为:[%d]:[%s]
    ",SQLCODE,SQLERRMC);
    #endif
           EXEC SQL ROLLBACK;
           DisConnectDataBase();
           exit(1);
       }
      /*提交删除信息*/
       EXEC SQL COMMIT;   
         
    /*循环处理目录下的文件*/
      for(  i=0; i<5; i++)                 //while ( *data_dir[i++] )
      {
       if ( (pDirectory=opendir(data_dir[i]))==NULL ){
        
              printf("打开目录[%s]失败.
    ",data_dir[i]);
              continue;    
       }
       
       while( (dirp=readdir(pDirectory))!=NULL ){
        
       if (strcmp(dirp->d_name,".")==0 ||
          strcmp(dirp->d_name,"..")==0)
          {
           continue;
         } 
            
       sprintf(pFileName,"%s/%s",data_dir[i],dirp->d_name);
       
    #ifdef DEBUG
       printf("文件名为: [%s].
    ",dirp->d_name);     
    #endif
       
       if( stat(pFileName,&st) <0 ){
        
          printf("读文件[%s]到文件结构失败.
    ",dirp->d_name);
          continue;
       }
       /*得到文件最后修改时间*/   
       file_mtime=st.st_mtime;
       strftime(szDate,15,"%Y%m%d%H%S",localtime(&file_mtime));
       strcpy(file_create_date,szDate);   
       
       /*得到文件大小*/
       file_size=st.st_size;
       
       /*得到文件名*/   
       //getFileName(szFileName,filename);
       strcpy(file_name,dirp->d_name);
       
       /*得到接口序号*/
       strncpy(szOrderId,file_name+1,5);
       szOrderId[6]='';
       orderid=atol(szOrderId);
       
       /*将文件信息入库*/
       EXEC SQL INSERT
       INTO MASAETL.ETL_LINK_FILE(FILEDATE,ORDER_ID,FILENAME,FILECREATEDATE,FILESIZE)
          VALUES(:file_date, :orderid, :file_name,TO_DATE( :file_create_date,'YYYYMMDDHH24MISS'), :file_size);
       
       /*处理执行SQL异常*/
       if ( SQLCODE ){
        
    #ifdef DEBUG
        printf("向数据库中写入文件信息失败,原因为:[%d]:[%s]
    ",SQLCODE,SQLERRMC);
    #endif
           EXEC SQL ROLLBACK;
           continue;
       }
       /*提交录入信息*/
       EXEC SQL COMMIT; 
      }
       /*关闭目录*/
       closedir(pDirectory);        
      }
      
      /*断开数据库连接*/
      DisConnectDataBase();
      return 0;
    }
    学无止境
  • 相关阅读:
    software architect
    bmh算法
    程序动态切片技术研究
    chm便捷制作
    protobuffer源码解读
    字符串搜索算法比较
    软件架构重组:实践需要和当前做法
    游戏素材制作
    ea(enterprise architect) 相关资料集锦
    vs开启工程非常卡分析和解决
  • 原文地址:https://www.cnblogs.com/tychyg/p/4868547.html
Copyright © 2011-2022 走看看