2007年,当时项目所有ETL采用C编写,实现了ETL基本功能。当接口很多时,为保证文件获取效率,做好接口可配置;文件维护中经常会出现接口晚到情况,需要有一种方法能将接口晚到信息写入数据库,便于短信告警。当时刚学习Pro*C不久,就实现了该方法, 如下
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <time.h> #include <sys/wait.h> #include <errno.h> #include <sys/types.h> #include <limits.h> #include <sqlda.h> #include <sqlcpr.h> /*定义数据库连接信息*/ #define USERNAME "masaetl" #define PASSWORD "masaetl" #define ORACLESID "DWDB2" #define MAX_MSG_LENGTH 128 #define MAX_CMD_LENGTH 1024 #define TRUE 1 /*定义告警文件生成目录*/ const char *alarm_path="/ETL_FS/etlfs/interface/toptea"; /*定义处理日期,内部链接的静态变量*/ 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 /*执行应用程序说明*/ /*getlinkdata程序每执行一次得到最后提供的晚到接口后都会执行*/ const char * getlinkfile="/ETL_FS/etlfs/interface/service/public/proc/getlinkdata"; /*getlatefile.sh根据得到的晚到接口列表自动提取接口文件并进行链接*/ const char * getlatefile="/ETL_FS/etlfs/interface/service/public/proc/getlatefile.sh"; void sqlerror(); /*处理SQL错误*/ int ConnectDataBase(); /*链接数据库*/ void DisConnectDataBase(); /*断开数据库连接*/ char *getYestDate(char *szDate); /*得到前一天的日期,格式"YYYYMMDD"*/ char *getFileName(const char *szFilePath,char *szFileName); /*从字符串中得到文件名*/ int getAlarmFile(const char *alarmFile); /*生成告警文件*/ char *substitute(char *src,const char *sMatch,const char *sReplace); /*将源字符串中子字符串替换*/ /************************************** *** 功能: 提取运行在数据库级报错信息 *** 输入变量: *** 输出变量: ***************************************/ 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={'