参考:PRO C 程序
代码已经编译调试,可以执行。
/*********************************************
filename: migsngl.pc
function: 动态游标
author: 吴家应
date: 20110210
***********************************************/
#include "pub.h"
#include <setjmp.h>
EXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE sqlda;
#define MAX_ITEMS 40
#define MAX_VNAME_LEN 30
#define MAX_INAME_LEN 30
#ifndef NULL
#define NULL 0
#endif
char sG_OperCode[9];
char * dml_commands[]={"SELECT","select",
"INSERT","insert",
"UPDATE","update",
"DELETE","delete"
};
SQLDA * bind_dp;
SQLDA * select_dp;
/*串型宿主变量,存放动态sql语句*/
EXEC SQL BEGIN DECLARE SECTION;
char sql_statement[1024];
EXEC SQL VAR sql_statement IS STRING(1024);
EXEC SQL END DECLARE SECTION;
int get_sql_statement(void);
int alloc_descriptors();
void set_bind_variables(void);
void process_select_list();
int main(int argc, char **argv)
{
int parse_flag = 0;
int i = 0;
strcpy(sG_OperCode,"sqldatest");
/** 登陆数据库**/
open_db();
/*为选择和结合描述区分配空间*/
if(alloc_descriptors(MAX_ITEMS,MAX_VNAME_LEN,MAX_INAME_LEN)!= 0 )
{
printf("alloc_descriptors error/n");
exit(1);
}
for(;;)
{
if( get_sql_statement()!=0 )
{
printf("获取sql失败/n");
break;
}
EXEC SQL WHENEVER SQLERROR DO sql_error();
parse_flag = 1;
printf("wjy sql_statement=%s /n",sql_statement);
EXEC SQL PREPARE S FROM :sql_statement;
parse_flag = 0;
EXEC SQL DECLARE C CURSOR FOR S;
/*为sql语句中的虚拟输入宿主变量设置结合变量*/
set_bind_variables();
EXEC SQL OPEN C USING DESCRIPTOR bind_dp;
process_select_list();
for( i=0;i<8;i++)
{
if(strncmp(sql_statement,dml_commands[i],6) == 0)
{
printf("/n %d row %c processed./n",sqlca.sqlerrd[2],sqlca.sqlerrd[2] == 1?'/0':'s');
break;
}
}
}
for( i=0;i<MAX_ITEMS;i++ )
{
if( bind_dp->V[i] != (char *)NULL )
free(bind_dp->V[i]);
free(bind_dp->I[i]);
if( select_dp->V[i] != (char *)NULL )
free(select_dp->V[i]);
free(select_dp->I[i]);
}
sqlclu(bind_dp);
sqlclu(select_dp);
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL CLOSE C;
close_db();
return 0;
}
/********************************
name: alloc_descriptors()
function: 分配选择区和结合区
********************************/
int alloc_descriptors(size,max_vname_len,max_iname_len)
int size;
int max_vname_len;
int max_iname_len;
{
printf("分配资源===开始/n");
int i;
/*分配结合描述区*/
if( (bind_dp=sqlald(size,max_vname_len,max_iname_len))==(SQLDA *)NULL )
{
printf("cannot allocate memory for bind descriptor/n");
return -1;
}
/*分配选择描述区*/
if((select_dp=sqlald(size,max_vname_len,max_iname_len))==(SQLDA *)NULL)
{
printf("cannot allocate memory for select descriptor/n");
return -1;
}
select_dp->N=MAX_ITEMS;
/*分配指向换从取的指针*/
for(i=0;i<MAX_ITEMS;i++)
bind_dp->I[i]=(short *)malloc(sizeof(short *));
for(i=0;i<MAX_ITEMS;i++)
bind_dp->V[i]=(short *)malloc(max_vname_len);
for(i=0;i<MAX_ITEMS;i++)
select_dp->I[i]=(short *)malloc(sizeof(short *));
for(i=0;i<MAX_ITEMS;i++)
select_dp->V[i]=(short *)malloc(max_vname_len);
printf("分配资源===结束/n");
return 0;
}
/********************************
函数名:get_sql_statement()
说 明: 取SQL语句
********************************/
int get_sql_statement()
{
printf("获取sql===开始/n");
char *cp;
char linebuf[256];
int iter;
memset(linebuf,'/0',sizeof(linebuf));
for(iter=2;;)
{
if(iter==2)
{
printf("/nSQL:");
sql_statement[0]='/0';
}
fgets(linebuf,sizeof(linebuf),stdin);
cp=strrchr(linebuf,'/0');
if(cp && cp !=linebuf)
*cp=' ';
else if(cp==linebuf)
{
continue;
}
if( (strncmp(linebuf,"exit",4)) == 0 )
{
return -1;
}
strcat(sql_statement,linebuf);
if( (cp=strrchr(sql_statement,';'))!=(char *)NULL )
{
*cp = '/0';
break;
}
else
{
printf("%3d/n",iter++);
}
printf("linebuf=%s/n",sql_statement);
}
printf("获取sql===结束/n");
return 0;
}
/**************************************************
name: set_bind_variables()
function: 设置结合变量,把结合变量的信息存入SQLDA
****************************************************/
void set_bind_variables()
{
printf("sqlda信息写入===开始/n");
int i,n;
char bind_var[64];
EXEC SQL WHENEVER SQLERROR DO sql_error();
/*初始化数组元素个数*/
bind_dp->N = MAX_ITEMS;
/*对实际宿主变量描述*/
EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp;
/*F是负数,结合变量过多*/
if( bind_dp->F < 0 )
{
printf("Too many bind variables (%d),maximum is %d",bind_dp->F,MAX_ITEMS);
return ;
}
/*默认的最大值,赋值为实际发现数目*/
printf("set_bind_variables begin bind_dp->F:%d/n",bind_dp->F);
bind_dp->N = bind_dp->F;
for( i=0;i<bind_dp->F;i++ )
{
printf("/n Enter value for bind variable %.*s:",(int)bind_dp->C[i],bind_dp->S[i]);
/*存放SLI的变量*/
fgets(bind_var ,sizeof(bind_var),stdin);
n=strlen(bind_var) - 1;
bind_dp->L[i] = n;
/*为值分配缓冲区,并把值拷贝到缓冲区中*/
bind_dp->V[i] =(char *) realloc(bind_dp->V[i],(bind_dp->L[i]+1));
/*设置指示变量的值*/
if( (strncmp(bind_dp->V[i],"NULL",4) == 0) || (strncmp(bind_dp->V[i],"null",4) == 4 ))
*bind_dp->I[i] = -1;
else
*bind_dp->I[i] = 0;
bind_dp->T[i] = 1;
}
printf("sqlda信息写入===结束/n");
}
/*********************************************
name: process_select_list()
function: 处理选择表项
*********************************************/
void process_select_list()
{
int i,null_ok,precision,scale;
/*非select语句*/
if( (strncmp(sql_statement,"SELECT",6)) != 0 && (strncmp(sql_statement,"select",6) != 0))
{
select_dp->F = 0;
return;
}
select_dp->N = MAX_ITEMS;
EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp;
if( select_dp->F<0 )
{
printf("Too many select list/n");
return ;
}
select_dp->N = select_dp->F;
printf("/n");
printf("select_dp->F : %d type=%d/n",select_dp->F,select_dp->T[1]);
for( i=0;i<select_dp->F;i++ )
{
/*断开数据类型的高位(not null)*/
sqlnul(&(select_dp->T[i]),&(select_dp->T[i]),&null_ok);
switch(select_dp->T[i])
{
case 1: break;
case 2:
sqlprc( &(select_dp->L[i]),&precision,&scale);
if( precision == 0)
precision = 40;
select_dp->L[i] = precision + 2;
break;
case 8:
select_dp->L[i] =240;
break;
case 11:
select_dp->L[i] = 18;
break;
case 12:
select_dp->L[i] = 9;
break;
case 23:
break;
case 24:
select_dp->L[i] = 240;
break;
}
select_dp->V[i] =(char *)realloc(select_dp->V[i],select_dp->L[i]+1);
if( select_dp->T[i] == 2 )
printf("%.*s",select_dp->L[i],select_dp->S[i]);
else
{
/*打印字段名称*/
printf(" %-.*s",select_dp->L[i],select_dp->S[i]);
}
if(select_dp->T[i] != 24)
select_dp->T[i] = 1;
}
printf("/n/n");
EXEC SQL WHENEVER NOT FOUND GOTO end_select_loop;
for(;;)
{
EXEC SQL FETCH C USING DESCRIPTOR select_dp;
for( i=0;i<select_dp->F;i++)
{
if( *select_dp->I[i] < 0)
printf("%-*c",(int)select_dp->L[i]);
else
{
printf(" %-.*s",(int)select_dp->L[i],select_dp->V[i]);
}
}
printf("/n");
}
end_select_loop:
return;
}
sql_error()
{
printf("ssssssssssssss/n");
}