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("\n Oracle error detected: ");
   printf("\n%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={‘\0‘};
   char szChar[5];

   //若输入的参数为空,默认提取系统前一天的日期
   if ( *szDate ==‘\0‘ ){

      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("连接数据失败.\n");
}

/*得到处理日期*/
getYestDate(filedate);
strcpy(file_date,filedate);
#ifdef DEBUG
   printf("处理日期: [%s].\n",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]\n",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]失败.\n",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].\n",dirp->d_name);
#endif

   if( stat(pFileName,&st) <0 ){

      printf("读文件[%s]到文件结构失败.\n",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]=‘\0‘;
   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]\n",SQLCODE,SQLERRMC);
#endif
       EXEC SQL ROLLBACK;
       continue;
   }
   /*提交录入信息*/
   EXEC SQL COMMIT;
  }
   /*关闭目录*/
   closedir(pDirectory);
  }

  /*断开数据库连接*/
  DisConnectDataBase();
  return 0;
}
时间: 2024-08-01 16:19:40

ETL应用:使用Pro*C写入文件信息入库的方法的相关文章

java写入文件的几种方法分享

转自:http://www.jb51.net/article/47062.htm 一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所有现有的内容,然而,当指定一个true (布尔)值作为FileWritter构造函数的第二个参数,它会保留现有的内容,并追加新内容在文件的末尾. 1. 替换所有现有的内容与新的内容. new FileWriter(file); 2. 保留现有的内容和附加在该文件的末尾的新内容. new FileWr

java写入文件的几种方法

一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所有现有的内容,然而,当指定一个true (布尔)值作为FileWritter构造函数的第二个参数,它会保留现有的内容,并追加新内容在文件的末尾. 1. 替换所有现有的内容与新的内容. new FileWriter(file);2. 保留现有的内容和附加在该文件的末尾的新内容. new FileWriter(file,true); 追加文件示例 一个文本文件,命名为“javaio-

iOS开发小技巧--边接受数据边写入文件的两种方法

一.NSFileHanle 使用注意点:在往文件写入数据时,必须创建一个空的文件 指定文件写入的方式 -- 覆盖还是追加 最后记得关闭 <1>代码是在大文件传输的练习中截取的.写入数据之前,创建空的文件,初始化NSFileHandle类 <2>设置文件的写入方式,(不设置写入方式,默认的是覆盖写入数据)并且将接收到的数据写入空的文件 <3>最后务必把操作文件的对象关闭 二.NSOutPutStream 使用注意:使用这个类操作文件不用提前创建空的文件,但是要记得将str

ETL应用:使用shell实现文件级校验的方法

BI应用中,对接口规范性约束很重要,接口文件提供需要配套提供该文件的校验文件,校验文件格式如下: 序号 信息内容 数据类型及长度 说明 1 接口数据文件名称 CHAR(50) 2 文件的大小(字节数) NUMBER(20) 文件的物理存储大小 3 文件中包含的记录数 NUMBER(20) 4 数据日期 CHAR(10) 如果抽取周期为小时,则格式则格式为:YYYYMMDDHH(HH采用24小时制,取值00-23):如果抽取周期为日,则格式则格式为:YYYYMMDD:如果抽取周期为月,则格式为:Y

用字符流实现每个文件夹中创建包含所有文件信息的readme.txt

1 package com.readme; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 import java.util.Scanner; 10 11 /** 12 * @autho

文件打包代码更新 使用json记录打包文件信息

经过之前的几次试验 决定使用json记录打包文件信息 #include "Package.h" #include "json/json.h" #include <string> #include <iostream> /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   技术交流群 群号码:324

C#异步将文本内容写入文件

在C#/.NET中,将文本内容写入文件最简单的方法是调用 File.WriteAllText() 方法,但这个方法没有异步的实现,要想用异步,只能改用有些复杂的 FileStream.WriteAsync() 方法. 使用 FileStream.WriteAsync() 有2个需要注意的地方,1是要设置bufferSize,2是要将useAsync这个构造函数参数设置为true,示例调用代码如下: public async Task CommitAsync() { var bits = Enco

crontab里shell脚本将top信息写入文件

crontab里shell脚本将top信息写入文件: 注: 1.top -n 1代表执行1次退出(默认top是不退出的),-d 1代表每1秒执行1次 2.crontab里需加/bin/bash # crontab -e */5 * * * * /bin/bash /usr/local/bin/top.sh # vi top.sh #!/bin/bash Date=`date +%Y%m%d` Date2=`date +%Y%m%d_%H%M` Date3=`date +%Y%m%d -d "7

Python爬虫之利用BeautifulSoup爬取豆瓣小说(三)——将小说信息写入文件

1 #-*-coding:utf-8-*- 2 import urllib2 3 from bs4 import BeautifulSoup 4 5 class dbxs: 6 7 def __init__(self): 8 self.pageIndex = 0 9 self.enable = True 10 self.file = None 11 self.content = [] 12 13 14 #获取html页面的内容 15 def getPage(self, pageIndex): 1