pro*c 动态sql

动态SQL
在有些情况下, 在编码时SQL语句还不能完整地写出来, 而是在程序执行时才能构造出来(也就是说动态SQL语句在程序编译时语句的选择列表和确定, 变量数据大于0)。 这种在程序执行临时生成的SQL语句叫动态SQL语句. 利用动态SQL来编写Pro*C程序的方法叫动态SQL技术.
在下列情况之一不知道时, 使用动态SQL技术:
a. SQL语句的文本.
b. 宿主变量的个数。
c. 宿主变量的数据类型。
Oracle Pro*C 编程入门
d. 引用的数据库对象, 如列, 索引, 序列, 表, 用户名和视图.
实际上, 动态SQL在一般应用中用的相当普遍!
Oracle中动态SQL可用以下两种方法实现:
一个是Oracle自己的方法, 一个是ANSI的方法. 一般建议使用Oracle的方法,但对于较复杂的应用, 可以使用ANSI的方法, 因为这样可以使自己的程序简化。
下面先说Oracle自己的方法.
5.1 Oracle方法
一般来说, 应该使用一个字符串变量来表示动态SQL语句的文本。 但该文本不包含“EXEC SQL”和分号“;”以及下列嵌入式SQL命令:
ALLOCATE CLOSE DECLARE DESCRIBE
EXECUTE FETCH FREE GET
INCLUDE OPEN PREPARE SET
WHENEVER
5.1.1 动态SQL语句的处理过程
动态SQL语句的处理过程如下:
a. 构造动态SQL语句, 提示用户输入和构造一个动态SQL语句文本。
b. 分析该语句: Oracle对动态SQL语句文本进行语法检查, 并检查动态SQL语句所参照的数据库对象是否存在, 以及用户是否具有访问它所参照的对象的权限。
c. 为SQL语句结合宿主变量:在执行语句过程中, Oracle读取宿主变量地址, 并从这些变量中读取数据, 式将数据写入这此变量中。
d. 执行SQL语句, 实现数据库操作。
5.1.2 Oracle使用动态SQL的四种方法
Oracle提供了四种处理动态SQL的方法, 这四种方法从一到四依次变得复杂,从功能上说也是依次包含关系, 即前一种方法的功能可以完全由后一种方法实现。 用户可以根据每个任务的难易程度选择一种适合于自己的方法。
有关这四种方法的详细介绍请参考相关手册和DEMO程序.
a. 方法一
这种方法只能执行非查询语句, 且在非查询动态SQL语句内不能包含输入宿主变量占位符。
这种方法使用EXECUTE IMMEDIATE命令立即执行动态SQL语句, 所以在每次执行时, Oracle需要对语句进行重新解释。
如:
…
<连接数据库>
strcpy(str_sql,“DELETE FROM test001 WHERE name=’username’”);
Oracle Pro*C 编程入门
EXEC SQL EXECUTE IMMEDIATE :str_sql;
…
b. 方法二
这种方法也只能用于执行非查询语句, 并且允许非查询动态SQL语句内包含输入宿主变量占位符, 但它要求在预编译时刻动态SQL语句内的占位符数量及输入宿主变量的数据类型必须确定。
①. 准备阶段: 调用PREPARE语句准备需要执行的动态SQL语句, 这时Oracle对动态SQL语句进行语法分析, 检查它所参照的数据库对象等;
②. 执行阶段: 调用EXECUTE 命令执行准备好的动态SQL语句。
采用这种方式时, 动态SQL被准备好后可以被多次执行, 而不需要Oracle在
每次执行时重新解释SQL语句。
如:
…
<连接数据库>
strcpy(str_sql,“INSERT INTO test001 values (:K1,:K2,:K3)”);
EXEC SQL PREPARE test FROM :str_sql;
EXEC SQL EXECUTE test USING :uname, :uaddress,:usex;
…
占位符可以是随便给的一个字符, 单词等.它只起占位作用而没有实际意义.
c. 方法三
这种方法可以执行包括查询语句在内的动态SQL语句, 但它要求在预编译时刻动态SQL语句内选择列表项数,输入宿主变量占位符数据以及输入宿主变量的数据类型必须确定。 方法三以游标方式执行动态SQL语句, 它对SQL语句的处理过程为:
①. 准执行PREPARE命令准备SQL语句;
#实际就是把要执行的动态语句调入内存, 以
便以后对它进行操作。
②. 执行DECLARE命令声明游标;
③. 执行OPEN打开游标;
④. 调用FETCH语句提取游标;
⑤. 调用CLOSE语句关闭游标。
动态SQL语句中的数据库对象名称和列名可以在运行时刻指定, 便此时不能以宿主变量形式指定对象名称或列名.
其实就是多了一个游标的使用。
如下面程序:
<连接数据库>;
strcpy(sql_stmt, "SELECT name, address, sex FROM test001");
EXEC SQL PREPARE select_stmt FROM :sql_stmt;
EXEC SQL DECLARE c1 CURSOR FOR select_stmt;
EXEC SQL OPEN c1;
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while(1)
Oracle Pro*C 编程入门
{
EXEC SQL FETCH c1 INTO :Name, :address, :sex;
printf("The name is: %s, The Address is: %s, The sex is :%s\n", Name, address,
sex);
}
EXEC SQL CLOSE c1;
d. 方法四
使用描述符方式处理动态SQL语句,它可以执行包括查询语句在内的所有动态SQL语句。 这种方式对动态SQL语句的限制最小, 它不要求在预编译时确定动动态SQL语句内的选择列表项数,库占位符数量以及宿主变量数据类型, 这些元素只要在运行时刻能够确定即可。
也就是说这种方法适合于在程序编译时对程序中的SQL语句还一无所知的情况。
方法四通过使用SQLDA结构代替宿主变量, 并通过调用DESCRIBE SELECT LIST或DESCRIBE BIND VARIABLES语句来检索选择列表项和结合变量(即宿主变量)描述信息, 从而使应用程序能够在运行时刻处理这种类型的动态SQL语句。
当SQLDA结构用于存列表信息项信息时, 它们被称做查询描述符; 当SQLDA结构用于存储结合变量信息时, 它们被称作结合描述符。
SQLDA结构的详细信息较长, 请参考相关书籍或手册。
这三种方法中前三种比较简单, 这里就不多说了, 方法四最为灵活, 功能最全,
但是也最为复杂. 使用方法共可分为以下18个步骤(请参考以下18个步骤去看例
程):
⑴. 在宿主变量声明区域声明字符串型宿主变量, 用它存储动态语句文本。
⑵. 声明查询和结合描述符。
⑶. 为查询和结合描述符分配内存空间;
⑷. 设置描述符能够最多描述的选择列表项和占位符数量;
⑸. 将动态语句文本拷贝到前面声明的宿主变量字符串中;
⑹. 调用PREPARE语句准备宿主变量字符串中的动态语句;
⑺. 为查询语句声明游标;
⑻. 描述结合变量,填充结合描述符;
⑼. 用DESCRIBE 语句所检索到的占位符实际数据(F)设置结合描述符中的占位符数据量, 即N元素;
⑽. 为DESCRIBE语句所检索到的结合变量分配内存, 并为各个结合变量提供数值;
⑾. 使用结合描述符打开游标;
⑿. 描述选择列表, 填充查询描述符;
⒀. 将查询描述符中的选择列表项数值设为DESCRIBE 语句所检索到的动态SQL语句中的实际选择列表项数;
⒁. 重新设置选择列有项的长度和数据类型;
⒂. 执行FETCH语句, 将数据库表中的数据提取到查询描述符所指向的数据缓冲区中;
⒃. 处理FETCH语句返回的选择列值;
⒄. 释放应用程序为选择列, 占位符, 指示符变量和描述符所申请的内存空
Oracle Pro*C 编程入门

5.2 ANSI方法
ANSI的方法如下:
5.2.1 使用ANSI方法的一些注意事项
Pro*C 应用程序的使用ANSI处理方法时, 必须将DYNAMIC 预编译选项值设置为
ANSI。 此外, 还需将TYPE_CODE选项设为ANSI。(这一点要十分注意, 因为这两
个选项不加会出现意想不到的错误,比如说: 如果不加TYPE_CODE, 程序一样可以
编译通过, 但是执行的结果却和你原来的的想法大相径庭)
5.2.2 ANSI方法和Oracle方法的不同
ANSI方法和Oracle方法相比有以下不同:
①. Oracle处理方法不支持对象类型, 游标变量, 结构数组, DML语句的RETURNING子句, 多字节字符变量
和LOB等,而ANSI处理方法支持所有的Oracle数据类型。
②. ANSI处理方法所使用的描述符为C/C++结构变量, 它们由应用程序申请,释放和维护,而ANSI处理方法所使用的描述符则为SQL描述符, 它们由Oracle内部维护。
正是由于ANSI方法所使用的描述符是由Oracle内部维护, 所以ANSI方法比以上
方法四少了一些对于描述符的操作,
比如分配内存空间等。
5.2.3 ANSI处理方法对动态SQL语句的处理步骤
ANSI处理方法对动态SQL语句的处理步骤为:
⑴. 声明宿主变量, 包括动态SQL语句存储缓冲区;
⑵. 为输入,输出变量分配描述符;
⑶. 将动态语句文本拷贝到前面(1)中声明的宿主变量字符串中;
⑷. 调用PREPARE语句准备宿主变量字符串中的动态语句;
#这一步实际上是对SQL语句进行语法分析, 检查
它所参照的数据库对象。
⑸. 用DESCRIBE语句描述输入操作;
#目的是读取动态SQL语句中的输入变量和输出变量等
描述信息,将它们存储到指定的输入描述符和输出描
述符中。
⑹. 声明动态游标;
⑺. 用SET DESCRIPTOR 语句设置输出描述符;
Oracle Pro*C 编程入门
⑻. 打开游标;
⑼. 提取游标数据;
⑽. 处理所提取的游标数据;
⑾. 关闭游标;
⑿. 释放输入,输出描述符;

注意: 如果用ANSI方法处理非查询语句时, 就没必要申请输出描述符!以上所列的
步骤可根据各自的应用进行增删!
比如说, 像没有参数的delete, insert等语句的处理就可以简化为以下四步:
a. 准备语句;
b. 声明游标;
c. 打开游标。
d. 关闭游标;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值