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. 2017-5-14 湘潭市赛 Highway 先获得直径S,T。则一开始S,T相连,然后其他的点如果离S更远那么连在S,否则T;

    Highway Accepted : Submit : Time Limit : MS Memory Limit : KB Highway In ICPCCamp there were n towns ...

  2. python第四周迭代器生成器序列化面向过程递归

      第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...

  3. 23:LVS客户端配置脚本案例

    [root@web03 scripts]# cat prevent_arp.sh #!/bin/bash lo_ip=$(ip a s lo|grep "10.0.0.1[3]/32&quo ...

  4. Spring MVC3.0.5搭建全程

    http://aokunsang.iteye.com/blog/1279322 ——————————————————————————————————————————————————

  5. Ext扩展的QQ表情选择面板

    Ext扩展的QQ表情选择面板 define(function () { EmoteChooser = function(cfg){ this.width=340; this.height=112; t ...

  6. java 获取网页指定内容-2(实践+修改)

    import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; ...

  7. ThinkPHP与EasyUI整合之二(datagrid):删除多条记录

    学习EasyUI已有一段时间了,现在开始逐步把平时学习的细节和难点记录下来. 1. datagrid选中多条记录的语句是: var rows = $('#dg').datagrid('getSelec ...

  8. weixin oauth 授权

    1. 先了解下请求授权页面的构造方式:   https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_u ...

  9. 41个Web开发者必须收藏的JavaScript实用技巧

    1. 将彻底屏蔽鼠标右键 oncontextmenu=”window.event.returnValue=false” < table border oncontextmenu=return(f ...

  10. LeetCode: Validate Binary Search Tree [098]

    [题目] Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defin ...