|
yulihua49 发表于 2012-11-14 10:59 ![]()
好,那我们握手言和了。
在动态解析数据时,可能其他工具开销都比较大。
oci可以高效解决数据动态解析 ...
这个PRO*C,也看看吧:
- //参数: 发生错误的函数名
- // 错误的信息
- //返回值:proc*c 的结果
- void SqlError(char* func, char* msg)
- {
- /* This function handles the SQL Errors and displays them */
- char err_msg[128]="";
- size_t buf_len=0, msg_len=0;
- EXEC SQL WHENEVER SQLERROR CONTINUE;
- LogMsg(MSG_INFO, "Error %s in %s", msg, func);
- buf_len = sizeof(err_msg);
- sqlglm(err_msg, &buf_len, &msg_len);
- LogMsg(MSG_INFO, "%.*s", msg_len, err_msg);
- OracleDisconnect();
- exit(EXIT_FAILURE);
- }
- //连接oracle数据库
- //参数: 连接的字符串,格式 user\passwd@db
- //返回值:proc*c 的结果
- int OracleConnect(const char* str)
- {
- EXEC SQL BEGIN DECLARE SECTION;
- /*变量声明*/
- char con_str[256]="";
- EXEC SQL END DECLARE SECTION;
- strcpy(con_str, str);
- LogMsg(MSG_INFO, "Connecting to Oracle as %s", str);
- /* This function connects to the Oracle Database */
- exec sql whenever sqlerror do SqlError("oracle_connect","connecting");
- exec sql connect :con_str;
- LogMsg(MSG_INFO, "Connected. sqlca.sqlcode=%d", sqlca.sqlcode);
- #ifdef DEBUG
- EXEC SQL ALTER SESSION SET sql_trace=true;
- LogMsg(MSG_INFO, "Debug: Enabled SQL Trace for this session.");
- #endif
- return (sqlca.sqlcode);
- }
- //断开oracle的连接
- //返回值: proc*c 的结果
- int OracleDisconnect()
- {
- LogMsg(MSG_INFO, "Disconnecting from Oracle");
- /* This function disconnects from the Oracle Database */
- exec sql whenever sqlerror continue;
- exec sql commit work release;
- LogMsg(MSG_INFO, "Disconnected");
- return (sqlca.sqlcode);
- }
- //按空格左截字符串,
- //参数: 要处理的字符串
- //返回值: 处理后的字符串
- char* LTrim(char* InStr,int *StrLength)
- {
- int i;
- for (i = 0; InStr[i] == ' '; i++);
- *StrLength-=i;
- return (InStr + i);
- }
- //按空格右截字符串,
- //参数: 要处理的字符串
- //返回值: 处理后的字符串
- //char* RTrim(char* InStr)
- //{
- // int i;
- // for (i = strlen(InStr) - 1; InStr[i] == ' ' && i >= 0; i--)
- // InStr[i] = '\0';
- // return (InStr);
- //}
- char* RTrim(char* InStr,int *StrLength)
- {
- int i;
- for (i =*StrLength - 1; InStr[i] == ' ' && i >= 0; i--)
- InStr[i] = '\0';
- *StrLength = i+1;
- return (InStr);
- }
- //把oracle的数据导出成csv
- //参数: sql查询
- // 导出csv的文件名
- int Sql2CSV(const char* Query,const char *Path, const char* Filename, const int BatchCount)
- {
- /* 定义宿主变量 */
- exec sql begin declare section;
- char sql_query[4000];
- int output_count;
- int output_type;
- int output_len;
- char output_buffer[4000];
- short output_indicator;
- char name[31];
- int occurs;
- exec sql end declare section;
- int i = 0;
- int j = 1;
- int line_pos = 0;
- char* p = NULL;
- char temp_info[64] = "";
- char cur_date[64]="";
- char* line = malloc(10 * 1024 * BatchCount);
- char temp_filename[256] = "";
- FILE* out;
- GetCurDate(cur_date,-SECEND_PER_DAY);
- sprintf(temp_filename,"%s%s_%s.tmp",Path,cur_date,Filename);
- if ((out = fopen(temp_filename, "w")) == NULL)
- {
- LogMsg(MSG_ERROR, "open %s file failed ", temp_filename);
- return -1;
- }
- memset(sql_query, 0, sizeof(sql_query));
- strcpy(sql_query, Query);
- exec sql whenever sqlerror do SqlError("sql_to_csv()","NLS_DATE_FORMAT");
- EXEC SQL ALTER SESSION SET NLS_DATE_FORMAT = 'YYYYMMDDHH24:MI:SS';
- exec sql whenever sqlerror do SqlError("sql_to_csv()","prepare s");
- exec sql prepare s from :sql_query; /* prepare SQL statement for execution. */
- /* s should not be declared as a variable */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","declare c");
- exec sql declare c cursor for s; /* Declare cursor C1 for retrieving the */
- /* results of prepared statement s */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","allocate descriptor");
- exec sql allocate descriptor 'output_descriptor' with max 256 ; /* Allocate a descriptor to identify the */
- /* attributes of the output generated by */
- /* executing the prepared statement s */
- /* 选择列表项->输出描述区 */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","describe output s");
- exec sql describe output s using descriptor 'output_descriptor';
- /* 取得选择列表项个数 */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","get descriptor count ");
- exec sql get descriptor 'output_descriptor' :output_count = count;
- LogMsg(MSG_INFO, "column count:%d", output_count);
- Query_Column* pColumns = (Query_Column*) malloc(sizeof(Query_Column) * output_count);
- if (NULL==pColumns)
- return -2;
- /* 循环处理选择列表项 */
- for (i = 0 ; i != output_count ; ++i)
- {
- occurs = i + 1;
- /* 取得选择列表项的名称并输出 */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","get descriptor TYPE LENGTH name");
- exec sql get descriptor 'output_descriptor' value :occurs :output_type = TYPE, :output_len = LENGTH, :name = name;
- pColumns[i].type = output_type;
- pColumns[i].length = output_len;
- strcpy(pColumns[i].name, name);
- switch (pColumns[i].type)
- {
- case ANSI_CHARACTER_CODE:
- pColumns[i].length++;
- break;
- case DATE_CHARACTER_CODE:
- pColumns[i].length = 16;
- break;
- case NUMBER_CHARACTER_CODE:
- case FLOAT_CHARACTER_CODE:
- case VARNUM_CHARACTER_CODE:
- case DECIMALCHARACTER_CODE:
- pColumns[i].length = 0 != output_len ? output_len + 1 : DEFAULT_COL_LENGTH;
- break;
- default:
- pColumns[i].length = 0 != output_len ? output_len : DEFAULT_COL_LENGTH;
- break;
- }
- /* 设置选择列表项的类型和长度 */
- output_type = ANSI_CHARACTER_CODE;
- output_len = pColumns[i].length;
- exec sql whenever sqlerror do SqlError("sql_to_csv()","set descriptor TYPE LENGTH ");
- exec sql set descriptor 'output_descriptor' value :occurs
- type = :output_type , length = :output_len;
- }
- /* 循环处理选择列表项数据 */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","open c");
- exec sql open c;
- line_pos = 0;
- memset(line, 0, sizeof(line));
- /* 提取数据完毕->退出循环 */
- exec sql whenever not found do break;
- strcpy(temp_info,"fetch c ");
- //exec sql whenever sqlerror do SqlError("sql_to_csv()","fetch c ");
- for (j = 1; ; j++)
- {
- itoa_n(j,temp_info+8);
- exec sql whenever sqlerror do SqlError("sql_to_csv()",temp_info);
- /* 行数据->输出描述区 */
- exec sql fetch c into descriptor 'output_descriptor';
- /* 循环处理每列数据 */
- for (i = 0 ; i < output_count ; ++i)
- {
- if (0 != i)
- {
- line[line_pos++] = ',';
- }
- occurs = i + 1;
- /* 取得列数据和指示变量值 */
- exec sql whenever sqlerror do SqlError("sql_to_csv()","get descriptor value");
- exec sql get descriptor 'output_descriptor'
- value :occurs :output_buffer = data , :output_indicator = indicator;
- output_buffer[pColumns[i].length ] = '\0';
- /* 输出列数据 */
- if (output_indicator != -1)
- {
- output_len = pColumns[i].length;
- p = LTrim(RTrim(output_buffer,&output_len),&output_len);
- if ((ANSI_CHARACTER_CODE == pColumns[i].type || CHAR_CHARACTER_CODE == pColumns[i].type ) && strchr(p, ',') != NULL)
- {
- line[line_pos++] = '"';
- strcpy(line + line_pos, p);
- line_pos += output_len;
- line[line_pos++] = '"';
- }
- else
- {
- strcpy(line + line_pos, p);
- line_pos += output_len;
- }
- }
- }
- line[line_pos++] = '\n';
- if (0 == j % BatchCount)
- {
- fwrite(line, 1, line_pos, out);
- fflush(out);
- LogMsg(MSG_INFO, "export csv count:%10d", j);
- memset(line, 0, sizeof(line));
- line_pos = 0;
- }
- }
- j--;
- if (0 != j % BatchCount)
- {
- fwrite(line, 1, line_pos, out);
- LogMsg(MSG_INFO, "export csv count:%10d", j);
- }
- fclose(out);
- free(pColumns);
- free(line);
- exec sql close c;
- exec sql deallocate descriptor 'output_descriptor';
- char new_filename[256]="";
- sprintf(new_filename, "%s%s_%s_%d.csv",Path,cur_date,Filename,j);
- if (0==j){
- LogMsg(MSG_INFO,"export count is 0 ,delete temp file.");
- unlink(temp_filename);
- }else{
- unlink(new_filename);
- rename(temp_filename, new_filename);
- }
- return 0;
- }
- //从ini文件中读取匹配的内容
- //参数: ini文件名
- // 匹配上的内容
- // 匹配关键字
- /*-- GetIniParm -----------------------------------------------------------------------*/
- void GetIniParm(const char* ini_name, char* DestStr, const char* ParName)
- {
- char buf[1024];
- short found = 0;
- #ifdef DEBUG
- LogMsg(MSG_INFO, "Debug: GetIniParm(%s)", ParName);
- #endif
- char file_name[256]="";
- ConvertAbsolutePath(ini_name,file_name);
- FILE* F_ini;
- if ((F_ini = fopen( file_name, "r")) == NULL)
- {
- LogMsg(MSG_ERROR, "Error: Unable to open ini file <%s> for reading.", file_name);
- }
- memset(buf, 0, sizeof(buf));
- while (fgets(buf, 1023, F_ini) != NULL)
- {
- /* Get rid of the NEWLINE char */
- buf[strlen(buf)-1] = '\0';
- if ('#' == buf[0])
- continue;
- if (strstr(buf, ParName) != NULL)
- {
- found = 1;
- strcpy(DestStr, buf + strlen(ParName) + 1);
- LogMsg(MSG_INFO, "%s=%s", ParName, DestStr);
- break;
- }
- }
- if (!found)
- {
- LogMsg(MSG_ERROR, "Error: No parameter by the name of <%s> in <%s>", ParName, ini_name);
- }
- if (F_ini)
- {
- fclose(F_ini);
- }
- }
- //从命令行读取参数
- //参数: 参数数量
- // 参数内容
- // 参数存放的变量
- /*-- process_parms --------------------------------------------------------------------*/
- void ProcessInputParms(const int argc, char* argv[], Input_Parm* parm)
- {
- int i = 0;
- char temp_count[32] = "";
- for (i = 1; i < argc; i++)
- {
- if (strncmp(argv[i], "-i", 2) == 0)
- {
- strcpy(parm->ini_name, argv[++i]);
- }
- else if (strncmp(argv[i], "-v", 2) == 0)
- {
- printf("unload - Version %s\n", VERSION);
- exit(0);
- }
- else if (strncmp(argv[i], "-d", 2) == 0)
- {
- memset(temp_count, 0, sizeof(temp_count));
- strcpy(temp_count, argv[++i]);
- parm->is_debug = atoi(temp_count);
- }
- else if (strncmp(argv[i], "-b", 2) == 0)
- {
- memset(temp_count, 0, sizeof(temp_count));
- strcpy(temp_count, argv[++i]);
- parm->batch_count = atoi(temp_count);
- }
- else
- {
- Usage();
- exit(1);
- }
- }
- if ((strlen(parm->ini_name) == 0))
- {
- Usage();
- exit(1);
- }
- }
- //从ini文件中读取配置参数
- //参数: ini文件名称
- // 参数存放的变量
- void ProcessIniParms(const char* ini, Ini_Param* parms)
- {
- char dir_name[256]="";
- GetIniParm(ini, parms->shell_prg, "ShellPrg");
- strcpy(parms->shell_prg,ConvertAbsolutePath(parms->shell_prg,dir_name));
- // GetIniParm(ini, parms->log_dir, "LogDir");
- // ExtendDir(parms->log_dir);
- // if (! DirectoryExists(parms->log_dir))
- // CreateDir(parms->log_dir);
- GetIniParm(ini, parms->arc_dir, "ArcDir");
- ExtendDir(parms->arc_dir);
- strcpy (parms->arc_dir, ConvertAbsolutePath(parms->arc_dir,dir_name));
- if (! DirectoryExists(parms->arc_dir))
- CreateDir(parms->arc_dir);
- GetIniParm(ini, parms->db_conn_str, "DBConnStr");
- char count[32] = "";
- GetIniParm(ini, count, "ArcCount");
- parms->arc_count = atoi(count);
- parms->arc_para = malloc(sizeof(ArcPara) * parms->arc_count);
- if (NULL == parms->arc_para)
- exit(-1);
- char parm_name[32] = "";
- int i = 0;
- for (i = 0 ; i < parms->arc_count; i++)
- {
- sprintf(parm_name, "ArcSql%d", i + 1);
- GetIniParm(ini, parms->arc_para[i].arc_sql, parm_name);
- sprintf(parm_name, "ArcFile%d", i + 1);
- GetIniParm(ini, parms->arc_para[i].arc_file, parm_name);
- }
- }
- int main(int argc, char** argv)
- {
- ExtractFilePath(argv[0],app_dir);
- //printf("app_dir :%s\n",app_dir);
- EXEC SQL WHENEVER SQLERROR DO SqlError("main()","");
- int i = 0;
- char arc_filename[256] = "";
- Input_Parm input_parm;
- Ini_Param ini_parms;
- memset(&input_parm, 0, sizeof(input_parm));
- strcpy(input_parm.ini_name, "paraconfig.ini");
- input_parm.is_debug = 0;
- input_parm.batch_count = 500;
- memset(&ini_parms, 0, sizeof(ini_parms));
- ProcessInputParms(argc, argv, &input_parm);
- ProcessIniParms(input_parm.ini_name, &ini_parms);
- OracleConnect(ini_parms.db_conn_str);
- for (i = 0; i < ini_parms.arc_count; i++)
- {
- LogMsg(MSG_INFO, "begin run sql2csv sql : %s ", ini_parms.arc_para[i].arc_sql);
- LogMsg(MSG_INFO, "end run sql2csv result: %d ",
- Sql2CSV(ini_parms.arc_para[i].arc_sql,ini_parms.arc_dir, ini_parms.arc_para[i].arc_file, input_parm.batch_count));
- }
- OracleDisconnect();
- if (FileExists(ini_parms.shell_prg))
- RunShell(ini_parms.shell_prg);
- free(ini_parms.arc_para);
- exit(0);
- }
复制代码
|
|