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[][]={ "/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[];
/*调试代码时使用*/
#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 连接数据库失败 0 成功
***************************************/
int ConnectDataBase()
{
EXEC SQL BEGIN DECLARE SECTION;
char username[];
char password[];
char oraclesid[];
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 -;
}
return ;
}
/**************************************
*** 功能: 断开数据库连接
*** 输入变量:
*** 输出变量:
***************************************/
void DisConnectDataBase()
{
/*断开连接*/
EXEC SQL ROLLBACK WORK RELEASE;
exit();
}
/***************************************
** 功能 : 得到前一天的日期
*** 输入变量:
*** 输出变量:
****************************************/
char *getYestDate(char *szDate)
{
time_t yest;
struct tm ptime={'\0'};
char szChar[]; //若输入的参数为空,默认提取系统前一天的日期
if ( *szDate =='\0' ){ yest=time(NULL)-(time_t)(**);
strftime(szDate,,"%Y%m%d",localtime(&yest)); return szDate;
}
//提取年
memset(szChar,,sizeof(szChar));
strncpy(szChar,szDate,);
ptime.tm_year=atoi(szChar)-; //提取月
memset(szChar,,sizeof(szChar));
strncpy(szChar,szDate+,);
ptime.tm_mon=atoi(szChar)-; //提取日
memset(szChar,,sizeof(szChar));
strncpy(szChar,szDate+,);
ptime.tm_mday=atoi(szChar); yest=mktime(&ptime)-(time_t)(**);
strftime(szDate,,"%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+;
}
#ifdef DEBUG
printf("文件名称为: [%s]",szFileName);
#endif
return szFileName;
}
/***************************************
** 功能 : 主程序
****************************************/
int main( void )
{
int i=;
char *szOrderId;
char pFileName[];
char *filename; //文件名
char szDate[]; //日期 "yyyymmddhh24miss"
time_t file_mtime; //文件时间 struct stat st;
struct dirent *dirp;
DIR *pDirectory; /*定义数据库变量*/
EXEC SQL BEGIN DECLARE SECTION;
char file_date[]; //文件日期
long orderid; //序号(接口编号)
char file_name[]; //文件名称
long file_size; //文件大小
char file_create_date[]; //文件最后修改的时间
EXEC SQL END DECLARE SECTION; /*链接数据库*/
if( ConnectDataBase()< ){ 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 ( !=SQLCODE && !=SQLCODE ){ #ifdef DEBUG
printf("删除当日统计数据失败,原因为:[%d]:[%s]\n",SQLCODE,SQLERRMC);
#endif
EXEC SQL ROLLBACK;
DisConnectDataBase();
exit();
}
/*提交删除信息*/
EXEC SQL COMMIT; /*循环处理目录下的文件*/
for( i=; i<; 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,".")== ||
strcmp(dirp->d_name,"..")==)
{
continue;
} sprintf(pFileName,"%s/%s",data_dir[i],dirp->d_name); #ifdef DEBUG
printf("文件名为: [%s].\n",dirp->d_name);
#endif if( stat(pFileName,&st) < ){ printf("读文件[%s]到文件结构失败.\n",dirp->d_name);
continue;
}
/*得到文件最后修改时间*/
file_mtime=st.st_mtime;
strftime(szDate,,"%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+,);
szOrderId[]='\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 ;
}

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

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

    转自:http://www.jb51.net/article/47062.htm 一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所 ...

  2. java写入文件的几种方法小结

    一,FileWritter写入文件 FileWritter, 字符流写入字符到文件.默认情况下,它会使用新的内容取代所有现有的内容,然而,当指定一个true (布尔)值作为FileWritter构造函 ...

  3. [测试]java IO写入文件效率——几种方法比较

    各类写入方法 /** *1 按字节写入 FileOutputStream * * @param count 写入循环次数 * @param str 写入字符串 */ public void outpu ...

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

    一.NSFileHanle 使用注意点:在往文件写入数据时,必须创建一个空的文件 指定文件写入的方式 -- 覆盖还是追加 最后记得关闭 <1>代码是在大文件传输的练习中截取的.写入数据之前 ...

  5. Android 追加写入文件的三种方法

    一.使用FileOutputStream 使用FileOutputStream,在构造FileOutputStream时,把第二个参数设为true public static void method1 ...

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

    BI应用中,对接口规范性约束很重要,接口文件提供需要配套提供该文件的校验文件,校验文件格式如下: 序号 信息内容 数据类型及长度 说明 1 接口数据文件名称 CHAR(50) 2 文件的大小(字节数) ...

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

    package com.readme; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; i ...

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

    经过之前的几次试验 决定使用json记录打包文件信息 #include "Package.h" #include "json/json.h" #include ...

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

    在C#/.NET中,将文本内容写入文件最简单的方法是调用 File.WriteAllText() 方法,但这个方法没有异步的实现,要想用异步,只能改用有些复杂的 FileStream.WriteAsy ...

随机推荐

  1. 大数据(6) - MapReduce简易介绍入门

    一 MapReduce入门 MapReduce定义(简单来说就是hadoop的数据分析核心,理解其中的原理,则可以分析聚合一切需求) Mapreduce是一个分布式运算程序的编程框架,是用户开发“基于 ...

  2. CGI(Common Gateway Interface),通用网关接口

    通用网关接口,简称CGI,是一种根据请求信息动态产生回应内容的技术.通过CGI,Web 服务器可以将根据请求不同启动不同的外部程序,并将请求内容转发给该程序,在程序执行结束后,将执行结果作为回应返回给 ...

  3. weblogic 8.1教程之部署(三)

    在 weblogic 都配置好了之后.就能够部署项目了. 部署项目的时候,能够大体分为两个步骤: 1,创建缓冲池: 2,配置数据源. 先启动 weblogicserver.进入weblogic 的主页 ...

  4. Linq to SQL 语法查询(子查询 & in操作 & join )

    var 子查询 = from c in ctx.Customers                    where                        (from o in ctx.Ord ...

  5. Android-ViewPagerIndicator框架使用——Circle

    前言:Circle适用于应用新功能的展示页和商品的多张图片的展示功能. 1.定义布局文件:SampleCirclesDefault中添加了一个布局:simple_circles. 布局中定义一个Lin ...

  6. python3----函数(join)

    今天写python 100例时,有个题目是大致是这样的:已知输入形式是1+3+2+1,要求输出形式为1+1+2+3 一开始思路是将输入的字符串用split()函数划分成数组,在对数组进行排序,再用fo ...

  7. c++ 判断windows系统和进程是32位还是64位

    BOOL Is64BitOS() { typedef VOID (WINAPI *LPFN_GetNativeSystemInfo)( __out LPSYSTEM_INFO lpSystemInfo ...

  8. okhttp 通过网关请求服务端返回数据

    1.启动类代码 package com.tycoon.service; import org.springframework.boot.SpringApplication; import org.sp ...

  9. springboot1.4下hystrix dashboard Unable to connect to Command Metric Stream解决办法

    搜索了好多资料,最后查看了官网.但是还是解决了.和大家分享下喜悦心情 在 此项目properties中添加如下信息 修改完信息后再浏览器输入:http://localhost:9875/hystrix ...

  10. mysql 存储二进制数据

    晚上小研究了下MySQL存储于读取二进制数据的功能.关键步骤为以下三点: 最重要的一点:存储二进制数据的表的类型需要是blob类型(按长度不同分为tiny, media, long) 插入二进制数据时 ...