共有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、方法四
posted on 2007-09-28 11:09
有猫相伴的日子 阅读(6673)
评论(5) 编辑 收藏 所属分类:
unix/windows C 程序设计