Duangw

动态SQL

索引:

  1. 动态SQL处理步骤
  2. 动态SQL的两种管理方法
  3. 系统描述区
  4. SQLDA结构
  5. 动态SQL语句语法

1.动态SQL处理步骤

装配SQL语句文本;

用PREPARE准备语句;

用EXECUTE/OPEN或FETECH执行语句;

用FREE释放资源。

 

2.动态SQL的两种管理方法

方法对比
系统描述区 SQLDA
语言独立性 依赖语言
与X/OPEN标准一致 与X/OPEN标准一致
内部仍然分配SQLDA 向后兼容
内存分配对比
系统描述区 SQLDA
ALLOCATE DESCRIPTOR Malloc
DEALLOCATE DESCRIPTOR Free
DESCRIBE DESCRIBE
GET DESCRIPTOR
SET DESCRIPTOR

 

3.系统描述区

结构

系统描述区开始是一个COUNT,记录系统描述区中的变量数目或occurrences的数目。

之后是COUNT个变量/occurrences的描述结构。每个结构有如下属性:

预定义常数
常量 C数据类型 整型数
CCHARTYPE char 100
CSHORTTYPE short int 101
CINTTYPE int 102
CLONGTYPE long 103
CFLOATTYPE float 104
CDOUBLETYPE double 105
CDECIMALTYPE dec_t或struct decimal 106
CFIXCHARTYPE fixchar 107
CSTRINGTYPE string 108
CDATETYPE long 109
CMONEYTYPE dec_t或struct decimal 110
CDTIMETYPE dtime_t或struct dtime 111
CLOCATORTYPE loc_t 112
CVCHARTYPE varchar 113
CINVTYPE intrvl_t或struct intrvl 114
CFILETYPE char 115
X/OPEN标志

当编译时使用了X/OPEN标志,则在SET DESCRIPTOR语句中不能使用下列常数:

常数 SQL数据类型 整型数
SQLCHAR CHAR 0
SQLSMINT SMALLINT 1
SQLINT INTEGER 2
SQLFLOAT FLOAT 3
SQLSMFLOAT SMALLFLOAT 4
SQLDECIMAL DECIMAL 5
SQLSERIAL SERIAL 6
SQLDATE DATE 7
SQLMONEY MONEY 8
SQLDTIME DATETIME 10
SQLBYTES BYTE 11
SQLTEXT TEXT 12
SQLVCHAR VARCHAR 13
SQLINTEGERVL INTERVAL 14

必须使用下面的值,以保证X/OPEN的兼容性:

常数 SQL数据类型 整型数
XSQLCHAR CHAR 1
XSQLSMINT SMALLINT 5
XSQLINT INTEGER 4
XSQLFLOAT FLOAT 6
XSQLDECIMAL DECIMAL 3

 

4.SQLDA结构

struct sqlvar_struct
{
    short sqltype;     /* variable type		*/
    short sqllen;      /* length in bytes		*/
    char *sqldata;     /* pointer to data		*/
    short *sqlind;     /* pointer to indicator	*/
    char  *sqlname;    /* variable name		*/
    char  *sqlformat;  /* reserved for future use 	*/
    short sqlitype;    /* ind variable type		*/
    short sqlilen;     /* ind length in bytes		*/
    char *sqlidata;    /* ind data pointer		*/
};
struct sqlda
{
    short sqld;
    struct sqlvar_struct *sqlvar;
};

不同系统中的定义不尽相同。含义说明如下:

sqld:表示SELECT语句返回值的字段数目或带参数的动态SQL语句中的参数数目。也就是sqlvar指向结构的数目。

sqlvar:指向sqlvar_struct结构的指针。sqlvar_struct结构链描述了各字段或参数的必要信息,下标从0开始。

sqltype:传送数据的类型。

sqllen:字符数组(CHAR和VARCHAR)的字节大小;DATETIME和INTERVAL类型的编码修饰符的字节大小。

sqldata:指向字符数据的指针。

sqlind:指向短整型指示变量的指针。

sqlname:指向字符数组的指针,数组中存放字段名或传送的显示标签。

sqlformat:保留。

sqlitype:指示变量的类型。

sqlilen:指示变量的字节长度。

sqlidata:指向字符指示数据的指针。

 

5.动态SQL语句语法

(1).PREPARE
PREPARE  statement_id  FROM  sql_string;

其中,statement_id:语句标识符,可以是宿主变量;

sql_string:要准备的语句,可以是宿主变量,但语句中不能包含宿主变量。

该语句把sql发送到后端进行语法分析和分配空间。如果一条语句要反复执行,最好先准备该语句。

不能准备“SELECT … INTO …”语句,也不能准备如下语句:CLOSE、EXECUTE IMMEDIATE、FREE、PUT、DECLARE、FETCH、OPEN、WHENEVER、EXECUTE、FLUSH。

可以使用占位符“?”给表达式提供值,但不能用来表示数据库名、表名或字段名等对象。

statement_id对其所在的源程序中是全局的。所以,在同一个源文件中,一个语句标示符只能对应一条RDSQL语句;在同一个源文件的不同函数里可以引用同一个语句标示符;对于不同的原文件,语句标示符不能像外部变量那样相互引用。

(2).EXECUTE
EXECUTE { IMMEDIATE sql_string
        | statement_id
        [ USING  { variable_list
                | SQL DESCRIPTOR descriptor
                | DESCRIPTOR sqlda_pointer } ] }

运行事先准备好的sql语句,EXECUTE不能执行检索数据到宿主变量的SELECT语句,但可以执行“SELECT …INTO TEMP..”语句。

使用IMMEDIATE表示在一个步骤里既准备语句又执行语句。

(3).DESCRIBE
DESCRIBE statement_id
   { USING SQL DESCRIPTOR descriptr
   | INTO sqlda_pointer }

对于SELECT语句,DESCRIBE返回查询字段的部分信息。对于INSERT语句,DESCRIBE返回要输入参数的数目、数据类型和空间大小等信息。返回信息存放到系统描述区或SQLDA结构里。对于SQLDA结构,返回下列值:sqld、sqlvar->sqlname、sqlvar->sqltype、sqlvar->sqllen。

对于UPDATE或DELETE语句,如果没有WHERE语句,则把sqlca.sqlwarn.sqlwarn4的值设置为W。

DESCRIBE不检查WHERE子句。

对于不带INTO TEMP子句的SELECT语句,将sqlca.sqlcode设置为0;对于其他语句,将其设置为一个正整数,该数代表RDSQL语句的类型,其定义在sqlstype.h中。

(4).DECLARE
DECLARE cursor_name [ SCROLL ] CURSOR FOR statement_id;

说明SELECT游标,可通过语句标识符statement_id来说明事先准备的动态语句。

(5).OPEN
OPEN cursor_name [ { USING variable_list
                | SQL DESCRIPTOR descriptor
                | DESCRIPTOR sqlda_pointer } ]

为SELECT游标建立搜索准则并将其初始化。

为INSERT游标建立插入缓冲区,此时不能包含USING子句。

(6)FETCH
FETCH [ position ] cursor_name
   [ { INTO host_varlist
    | USING SQL DESCRIPTOR descriptor
    | USING DESCRIPTOR sqlda_pointer } ]
(7).PUT
PUT cusor_name
   [ {USING SQL DESCRIPTOR descriptor
    | USING DESCRIPTOR sqlda_pointer
    | FROM variable_list } ]
(8).FREE
FREE { cursor_id
     | statement_id }

释放游标标示符/变量,语句标示符/变量。

(9).ALLOCATE DESCRIPTOR
ALLOCATE DESCRIPTOR descriptor [ WITH MAX occurrence ]

其中,descriptor是系统描述区描述符,可以是宿主变量;

occurrence是动态sql语句中的占位符。WITH MAX指定最大的占位符数量,缺省为100。

该语句为系统描述区分配内存空间。

(10).DEALLOCATE DESCRIPTOR
DEALLOCATE DESCRIPTOR descriptor;

释放一个系统描述区。

无法释放SQLDA结构。

(11).GET DESCRIPTOR
GET DESCRIPTOR descriptor
  { host_variabe = COUNT
  | VALUE item_number
   host_variabe = item_info [, host_variable = item_info ] … }

其中item_info含义见系统描述区结构部分。

从系统描述区获取信息,把它们存放到所说明的宿主变量中。由如下三个功能:

(12).SET DESCRIPTOR
SET DESCRIPTOR descriptor
  { COUNT = value
  | VALUE item_number
   item_info = value [, item_info = value ] … }

设置描述符区的COUNT域和字段。

如果它是一个CHARACTER项,则必须设置LENGTH域。

对于DATETIME或INTERVAL域,可以把DATA域设置为一个内部DATETIME或INTERVAL类型,或作为一个字符串。如果设置了一个字符串,必须把LENGTH域设置到编码修饰符值中。