基本概念
在有些情况下, 在编码时 SQL 语句还不能完整地写出来, 而是在程序执行时才能
构造出来,这种在程序执行临时生成的 SQL 语句叫动态 SQL 语句. 利用动态 SQL 来
编写 Pro*C 程序的方法叫动态 SQL 技术!
目的:加强应用程序的功能和灵活
静态SQL —- 在编写应用程序时,使用EXEC SQL关键字直接嵌入的SQL语句;在proc编译应用程序生成c语言的时,都已经确定
动态SQL —- 在运行应用程序时,由用户动态输入的SQL语句。
在下列情况之一不知道时, 使用动态 SQL 技术:
SQL 语句的文本.
宿主变量的个数。
宿主变量的数据类型
引用的数据库对象, 如列, 索引, 序列, 表, 用户名和视图.
Oracle 中动态 SQL 可用以下两种方法实现:一个是 Oracle 自己的方法, 一个是 ANSI 的方法. 一般建议使用 Oracle 的方法,
但对于较复杂的应用, 可以使用 ANSI 的方法, 因为这样可以使自己的程序简化。
动态SQL1
语法:
EXEC SQL EXECUTE IMMEDIATE :host_string
host_string 字符串
限制
不能执行select语言,仅适用于非select语句
在sqlplus上运行的命令,都可以拿过来来执行
语句中不包含输入宿主变量–一个宿主指针变量指向一块内存空间(存有用户输入的SQL语句)
常用于仅执行一次的动态语句
对重复执行多次的动态SQL语句,降低执行效率
nt main01()
{
int ret = 0;
int i = 0;
char choosechar;
memset(mySql, 0, sizeof(mySql));
pSql = NULL;
EXEC SQL WHENEVER SQLERROR DO sqlerr02();
connet();
pSql = mySql;
//循环处理sql语言
for(;;)
{
printf("\nplease enter sql(not select ): ");
gets(mySql);
//scanf("%s", mySql); --空格截断
printf("mysql:%s\n", mySql);
printf("任意键继续....\n");
getchar();
EXEC SQL EXECUTE IMMEDIATE :pSql;
EXEC SQL COMMIT;
printf("继续执行吗?\n");
scanf("%c", &choosechar);
fflush(stdin);
if (choosechar=='n' || choosechar=='N')
{
break;
}
}
EXEC SQL COMMIT WORK RELEASE;
printf("return ok...\n");
return ret ;
}
动态SQL2
使用PREPARE命令准备SQL语句
EXEC SQL PREPARE statement_name FROM :host_string;
statement_name: 标识符,
host_string:含SQL语句的字符串
使用EXECUTE命令执行SQL语句
EXEC SQL EXECUTE statement_name [USING :host_variable]
如果SQL语句要通过宿主变量赋值,输入SQL语句时要用占位符仅适用于非select语句
可包含虚拟输入宿主变量和指示器变量,其个数和类型在预编译时已知
int main02()
{
int ret = 0;
int i = 0;
char choosechar;
memset(mySql, 0, sizeof(mySql));
pSql = NULL;
EXEC SQL WHENEVER SQLERROR DO sqlerr02();
connet();
pSql = mySql;
//循环处理sql语言
for(;;)
{
printf("\n请输入要更新部门编号 ");
scanf("%d", &deptno);
printf("\n请输入要新loc值 ");
scanf("%s", loc);
//准备动态sql
EXEC SQL PREPARE my_pre_sql FROM 'update dept set loc = :a where deptno = :b';
//执行动态sql
EXEC SQL EXECUTE my_pre_sql USING :loc, :deptno;
EXEC SQL COMMIT;
printf("\n 按任意键继续? ");
getchar();
printf("\n退出键入n, 其他继续? ");
scanf("%c", &choosechar);
fflush(stdin);
if (choosechar=='n' || choosechar=='N')
{
break;
}
}
EXEC SQL COMMIT WORK RELEASE;
printf("return ok...\n");
return ret ;
}
动态SQL3
使用PREPARE命令准备SQL语句
EXEC SQL PREPARE statement_name FROM :host_string;
statement_name: 标识符,
host_string:含SQL语句的字符串
使用DECLARE命令定义游标,可以结合游标一块使用
EXEC SQL DECLARE cursor_name CURSOR FOR statement_name;
EXEC SQL OPEN cursor_name [using host_variable_list]
EXEC SQL FETCH cursor_name INTO host_variable_list
EXEC SQL CLOSE cursor_name
查询部门号大于10的所有部门信息
动态sql3 处理选择列表项(select查询出来的结果列数固定) 和 输入宿主变量个数一定
本质:
输入宿主变量个数固定 查询条件固定
输出宿主变量个数固定 返回结果固定
//可以结合游标一块使用
int main()
{
int ret = 0;
int i = 0;
char choosechar;
memset(mySql,