sqlda实例

该博客主要介绍了如何在PRO C程序中使用SQLDA结构来处理动态游标,包括动态SQL语句的创建、结合描述区和选择描述区的分配、设置结合变量以及处理选择列表。示例代码展示了动态游标的使用流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考: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");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值