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. UTF-8和GBK的区别

    GBK是在国家标准GB2312基础上扩容后兼容GB2312的标准(好像还不是国家标准).GBK编码专门用来解决中文编码的,是双字节的.不论中英文都是双字节的. UTF-8编码是用以解决国际上字符的一种 ...

  2. SecurCRT 远程linux 输入中文及 oracle 查询出文号问题

    一. 首先确认你的linux是否设置了支持中文 cat /etc/sysconfig/i18n 其中: LANG 变量是 language 的简称, 这个变量时决定系统的默认语言, 即系统菜单, 程序 ...

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

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

  4. Hibernate体系结构

    Hibernate架构包括许多对象持久对象,会话工厂,事务工厂,连接工厂,会话,事务等. hibernate架构中有4层Java应用层,hibernate框架层,反手api层和数据库层.请参见hibe ...

  5. makefile编写---:= ?= += =的区别

    在Makefile中我们经常看到 = := ?= +=这几个赋值运算符,那么他们有什么区别呢?我们来做个简单的实验 新建一个Makefile,内容为:ifdef DEFINE_VRE    VRE = ...

  6. cobbler 更换dns和dhcp服务器为dnsmasq

    1) 需要配置/etc/cobbler/module.conf, 把manage_dns和manage_dhcp改为manage_dnsmasq 2) 重启cobbler和dnsmasq服务,dnsm ...

  7. 初探webpack之环境配置

    先感叹一句,前端的发展真是太快了,ng和bb还没怎么学好就要过时了.现在感觉react当是未来的一个大方向. 以前一直用的grunt,不过前段时间作者已经停止更新了.正好webpack风头正盛,咱也不 ...

  8. Win7系统安装 MySQL 8.0.11

    1. 下载 MySQL 8.0.11 版本 下载地址: https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-winx64.zip 2. 下载 ...

  9. 1366 贫富差距(floyed)

    1366 贫富差距 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 一个国家有N个公民,标记为0,1,2,...,N-1,每个公民有一 ...

  10. 160824、ionic添加地图站点

    1.基本的地图显示 <!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset= ...