第四章 动态SQL语句
嵌入式的SQL有两种主要的形式:静态的SQL和动态的SQL。静态的SQL语句是在编写程序时要定义所有的SQL语句,如INSERT、SELECT等普通的SQL语句。对于动态的SQL的情形,SQL语句可以被应用程序在运行时构造。
ESQL/C提供了处理在编译时未知的SQL语句的手段,通常的ESQL/C程序,只要显式地嵌入SQL语句就能实现所要求的功能了,但在有些特定的应用中,程序在编译时并不知道语句的内容,需要在程序运行中捕获并完成正确的操作,这样的程序有:
1.运行时用户才从键盘打入检索要求的交互式程序。
2.编写支持变化的数据库结构的程序,这些变化在编程时是未知的。
这两种情况都需要对动态定义的语句进行处理,也就是说,当应用程序不知道那些需要提前在数据库上执行的所有操作时,或操作的组合数目很大,以至于与其在静态SQL中把所有可能的组合都编码,倒不如动态地在程序中建立SQL串来得容易些。动态SQL中使用参数代替了宿主变量,这些参数可以嵌入在SQL语句中,并且在以后被值替换。动态SQL语句在提
高性能方面还有不小的影响。
4.1 动态SQL的相关语句
动态SQL的特性为:语句的说明与执行分为两步。第一步,PREPARE语句用于分析SQL语句,并且在必要时建立一个程序计划;第二步,用EXECUTE或定义游标来执行被预备好的SQL语句。这样一旦一条SQLsql语句替换表中内容语句经过预备处理后,就可重复执行它多次。假如仅执行一次的SQL语句那就不必做预备处理。与之相关的动态定义语句简要介绍如下:
1.PREPARE语句:将一字符串解释成一组SQL语句,并赋给它一个语句标识符,以后的
动态管理语句通过语句标识来引用这组SQL语句。
PREPARE语句的一般形式为:
PREPARE语句标识名from“SQL语句”;
或PREPARE语句标识名from :宿主变量;
2.EXECUTE语句:运行与其语句标识符对应的事先准备好的语句,对非select语句,用
EXECUTE来运行。
EXECUTE语句的一般形式为:
EXECUTE被预备的语句标识名[using宿主变量列]
3.DESCRIBE语句:确定已准备好的语句是否为select语句,如果是,则得到单一查
行的存贮要求,否则只返回语句类型。
4.DECLARE语句:为已准备好的select语句说明游标。
5.FREE语句:释放已准备好的语句或已打开的游标所占用的资源。
6.EXECUTE IMMEDIATE语句:立即执行语句,它接收一字符串,将其解释成SQL语句
并立即执行它,然后释放准备SQL语句所占用的资源。
4.2 非select语句的用法举例
例:
$ char state[128];
$ long p_num;
char num[12];
long atol();
...
sprintf(state,"delete from customer where customer_num=?");
$ prepare stateid from $ state; /*准备state中的语句*/
for(;;){
prinft{"Enter customer number:");
getline(num,12);
p_num=atol(num);
if(p_num==0)break;
$ execute stateid using $ p_num;
/*执行语句,用p_num的值替语句中的问号“?”*/
}
例:
int cust_update(cnum,lname)
exec sql begin declare section;
parameter long cnum;
parameter char *lname;
exec sql end declare section;
{
static int first = 1;
if (first){
first =0;
exec sql prepare pl from
"update customer set lname =? where cus_num =?";
sqlerr();
}
esql sql execute pl using :lname, :cnum;
sqlerr();
}
4.3 select语句的用法举例
在ESQL/C中直接嵌入的select语句,查询结果放入INTO子句的宿主变量中,然而在程序已被编译后交互地建立的select语句中,不能使用INTO子句,因为这时不能直接使用宿主变量。/*?????*/为此,ESQL/C提供了sqlda结构,该结构中包含了动态定义语句的所有信息。执行动态定义的select语句,需要以下几个步骤:
(1)说明一个指向sqlda结构的指针
(2)准备select语句,并赋给语句标识符
(3)执行语句describe为指针赋值,使其指向一结构链,链中每个结点含有查项的
描述,包括数据类型、长度、名字等
(4)为结构链中存放查询数据的指针分配空间
(5)为已准备好的语句说明游标
(6)打开游标
(7)执行语句来获取数据,并重复执行。
(8)关闭游标
例:
$ include sqlca;
$ include sqlda;
.
.
.
/*declare pointer to structure that
apportions the data from each row*/
struct sqlda *q_desc;
/*declare host variable to hold
statement string*/
$ char q_string[128];
/*make stores the current database*/
$ database stores;
.
.
.
/*At this point the SELECT statement
is assigned to q_string*/
/*prepare the SELECT statement*/
$ prepare q_id from $q_string;
/*identify the select_list*/
$ describe q_id into q_desc;
/*this section of the code must
allocate variables to receive
the data from the rows and
set the pointers in q_desc.
See the followng discussion*/
/*associate q_cursor with SELECT
statement*/
$ declare q_cursor cursor for q_id;
/*open q_cursor;create active set*/
$ open q_cursor;
/*loop through rows in active set*/
for(;;)
{
/*fetch next row from the active set*/
$ fetch q_cursor
using descriptor q_desc;
/*process data if fetch returned a row*/
if (sqlca.sqlcode==0)
{
/*process data*/
.
.
.
}
else
{
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论