共有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 ;
然后遍歷游標:
{
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 <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、方法四