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、方法四

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值