pro*c动态SQL技术

共有4种构方法构造动态SQL语句:
1、方法一:
       仅适用于非SELECT语句,且语句中不包含输入宿主变量。格式如下
       EXEC SQL EXECUTE  IMMEDIATE  :host_string  或
        EXEC SQL EXECUTE  IMMEDIATE  "UPDATE XX SET NAME=yyyy  HERE ID=1"

2、方法二:
  也只适用于非SELECT语句,SQL语句可包含虚拟输入宿主变量和指示器变量,但它们的个数和数据类型在预编译时必须是可知的。
         处理分三步:
        A、构造一个动态SQL语句。
        B、用PREPARE 语句来分析和命名该动态SQL语句
        C、用EXECUTE 来执行
     EXEC SQL PREPARE 用于分析一个动态SQL,如
        strcpy(sql_stmt,"DELETE FROM EMP  WHERE JOB=:v");
         EXEC SQL PREPARE stmt FROM :sql_stmt;
    EXECUTE 语句格式:
     EXEC SQL FOR <行数> EXECUTE  <动态语句> USING  <参数>
    EXEC SQL EXECUTE stmt USING :job;

3、方法三:
     方法三只适用于SELECT语句,语句中包含选择表项个数,和虚拟输入宿主变量个数在预编译时都是已知的,但是数据库的表、列名可能运行时指定。步骤如下:
     1、定义动态脚本。
     2、分析动态脚本。
     3、定义游标,游标的语句就是动态分析的名。
     代码例子:
        strcpy(sql_stmt,"SELECT SID,ENAME FROM EMP  WHERE JOB=:v");
         EXEC SQL PREPARE stmt FROM :sql_stmt;
        EXEC SQL DECLARE cur FOR  stmt ;

       然后遍历游标:

for(;;)
    {
         EXEC SQL for :n FETCH stud_cur  INTO :stud_id,:stud_age,:stud_n
ame,:stud_addr;
         rows=sqlca.sqlerrd[2];
printf("rows=%d\n",rows);
         int i;
if(sqlca.sqlcode<0) {
printf("ora err:%d",sqlca.sqlcode);
break;
}
rows=sqlca.sqlerrd[2]-n*j;
         for(i=0;i<rows;i++)
         {
              printf("%d--%d--%s--%s\n",stud_id[i],stud_age[i],stud_name
[i].arr,stud_addr[i].arr);
         }
         j++;
         printf("currsor %d times\n",j);
if ((sqlca.sqlcode == 1403) ) break;
    }

上面遍因游标是一次取N条记录的,因为stud_id等是数组,n为数组长度
一个完整的动态游标例子

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
EXEC SQL include sqlca;
#ifdef TRUE
#undef TRUE
#endif

#define TRUE 1

EXEC ORACLE OPTION (RELEASE_CURSOR = YES);
EXEC SQL BEGIN DECLARE SECTION;
                VARCHAR username[20];
                VARCHAR password[20];

EXEC SQL END DECLARE SECTION;


void sql_error()
{
    EXEC SQL WHENEVER SQLERROR CONTINUE;
    printf("\n Oracle error detected:\n");
    printf("\n%.70s\n",sqlca.sqlerrm.sqlerrmc);
    EXEC SQL ROLLBACK RELEASE;
    exit(1);
}
void dyna_cursor()
{
    EXEC SQL BEGIN DECLARE SECTION;
        char *sql_str;
        int stud_id;
        int stud_age;
        VARCHAR stud_name[20];
        VARCHAR stud_addr[60];
        int vage;  
    EXEC SQL END   DECLARE SECTION;
    sql_str=(char *)malloc(400);
    vage=3;
    strcpy(sql_str,"SELECT STUD_ID,STUD_NAME FROM PROC_STUD WHERE STUD_A
GE=:v1");
    EXEC SQL PREPARE S FROM :sql_str;
    EXEC SQL DECLARE C CURSOR  FOR S;
    printf("please input age :\n");
    scanf("%d",&vage);
    EXEC SQL OPEN C USING :vage;
    EXEC SQL WHENEVER NOT FOUND GOTO notfound;
    while(TRUE)
    {
        EXEC SQL FETCH C INTO :stud_id,:stud_name;
        /*stud_name.arr[stud_name.len]='\0';*/
        /*stud_name.len=strlen(stud_name.arr);*/
        printf("%d\t%s\n",stud_id,stud_name.arr);
    }
 notfound:
    printf("\nQuery Returned %d row %s\n",sqlca.sqlerrd[2],sql_str);
    EXEC SQL CLOSE C;
    EXEC SQL COMMIT RELEASE;
    printf("Have a good day!\n");
    exit(0);
 sqlerror:
    printf("%d %.*s\n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
    EXEC SQL WHENEVER SQLERROR CONTINUE;
    EXEC SQL CLOSE C;
    EXEC SQL ROLLBACK RELEASE;
    exit(1);
}


main()
{
     strcpy(username.arr,"gdnum_true");
     strcpy(password.arr,"gdnumtrue_10");
     username.len=strlen(username.arr);
     password.len=strlen(password.arr);

     EXEC SQL CONNECT :username IDENTIFIED BY :password;
     printf("sqlca.sqlcode=%d;\n",sqlca.sqlcode);
     printf("login user=%s\n",username.arr);
     dyna_cursor();
     exit(0);
}

4、方法四



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值