c oracle 返回行数,ORACLE PROC开发(2)

7.sqlda动态SQL预备知识

(1).sqlda的引用

EXEC SQL INCLUDE sqlda;

sqlda *bind_dp;

bind_dp = sqlald( … );

(2).sqlald函数

sqlald函数为sqlda结构分配空间。函数格式如下:

descriptor_name = sqlald(max_vars, max_name, max_ind_name );

其中:

max_vars:sqlda结构中要描述的选择表项或虚拟输入宿主变量的最大个数;

max_name:选择表项或虚拟输入宿主变量名字的最大长度;

max_ind_name:指示器变量名的最大长度。对于选择sqlda,该项设置为0。

一般用指针来引用sqlda。

(3).数据类型转换

对于选择描述区,DESCRIBE SELECT

LIST返回ORACLE的内部数据类型。通常,该内部数据类型正好对应所要用的外部数据类型;但是,个别的映射难以处理,因此,可以重新设置T变量的某些元素。ORACLE在FETCH时做必要的内部和外部数据类型的转换。

对于结合缓冲区,DESCRIBE BIND

VARIABLES并不返回实输入宿主变量的数据类型,而只返回它们的个数和名字。于是,必须显示设置数组T,以告诉ORACLE每一个实输入宿主变量的外部数据类型。ORACLE在OPEN时做外部和内部数据类型之间的必要转换。

除了设置T变量外,有些情况下,还要设置缓冲区长度。在FETCH之前必须重新设置L变量的相应元素,以告诉ORACLE所用的缓冲区长度。

库函数sqlprc()分离精度和定标。通常在DESCRIBE

SELECT LIST之后使用它,并且它的第一个参数时L[i]:

sqlprc( long *length, int *precision, int *scale );

其中,length存储一个ORACLE

NUMBER值得长度。长度存放在L[i],该值得定标和精度存放在相应的低字节和下一个高字节中;

precision存放NUMBER值精度。精度是有效位数,如果选择表项引用的是未指定大小的NUMBER值,则它被设置为0。在这种情况下,可假定为最大精度;

scale存放NUMBER值定标。定标指出在什么地方舍入。如,2:3.456

-> 3.46;-3:3456 -> 3000。

(4).处理Null/Not Null类型

对于每一个选择表列(不是表达式),DESCRIBE SELECT

LIST在T变量中返回一个Null/Not Null指示。如果第i个选择表项被强制为Not

Null,那么T[i]的高位被清除,否则被设置。

在OPEN或FETCH之前,如果Null位被设置的话,则必须清除它。使用库函数sqlnul来发现一个列是否允许Null,并清除该数据类型的Null状态位:

sqlnul(unsigned short *value_type, unsigned short *type_code, \

int *null_status );

其中,value_type存放一个选择表项的数据类型代码,即T[i];

type_code返回该选择表列的数据类型代码,其高位被清除;

null_status返回选择表列的Null状态。1表示允许Null;0表示不允许Null。

8.sqlda动态SQL基本处理步骤

(1).说明一个串型宿主变量

在说明段说明一个串型的宿主变量,以保存查询语句的文本。

EXEC SQL BEGIN DECLARE SECTION

VARCHAR select_stmt[120];

EXEC SQL END DECLARE SECTION

(2).说明SQLDA

说明选择和结合SQLDA。

EXEC SQL INCLUDE sqlda;

sqlda *select_des;

sqlda *bind_des;

(3).分配空间

分配选择和结合缓冲区的空间。

使用sqlald()函数分配,如果max_name非0,则分配由指针变量S、M和C寻址的数组。如果max_ind_name不是0,则分配由指针变量X、Y和Z寻址的数组。如果max_name和max_ind_name为0,则不分配相应的空间。

如果sqlald()成功,则返回该描述区的地址,失败则返回空指针。

select_des = sqlald(3, 5, 0);

bind_des = sqlald(3, 5, 4);

对于选择描述区,总是把max_ind_name设置为0。

(4).设置DESCRIBE的最大个数

设置能被DESCRIBE的选择表项和虚拟输入宿主变量的最大个数。

select_des->N = 3;

bind_des->N = 3;

(5).把查询文本存放在宿主串中

把查询语句文本存放在串型宿主变量中。

strcpy(select_stmt.arr, “select … where …” );

select_stmt.len = strlen(select_stmt.arr);

(6).分析查询语句

PREPARE宿主串中的查询语句。

EXEC SQL PREPARE sql_stmt FROM :select_stmt;

(7).说明一个光标

DECLARE一个查询光标。

EXEC SQL DEACLARE emp_cursor CURSOR FOR sql_stmt;

注意:对于此种方法的动态sql语句(不只是查询语句),都必须说明一个光标,在非查询语句情况下,打开光标即执行该动态sql语句。

(8).DESCRIBE实输入宿主变量

把实输入宿主变量DESCRIBE进结合描述区中。

EXEC SQL DESCRIBE BIND VARIABLES FOR sql_stmt INTO bind_des;

注意:在bind_des之前一定不加冒号。

(9).重新设置虚拟输入宿主变量的个数

把虚拟输入宿主变量的个数重新设置为DESCRIBE实际发现的个数。

bind_des->N = bind_des->F;

(10).为实输入宿主变量分配空间和取值

为DESCRIBE发现的实输入宿主变量取值和分配存储空间。

如:

bind_des->L[i] = strlen( hostval );

bind_des->V[i] = malloc(bind_des->L[i] + 1);

bind_des->I[i] = (unsigned short *)malloc(sizeof(short));

strcpy(bind_des->V[i], hostval);

bind_des->I[i] = 0;

bind_des->T[i] = 1;

(11).打开光标

用OPEN…USING打开与结合描述区相对应的光标。

EXEC SQL OPEN emp_cursor USING DESCRIPTOR bind_des;

注意:在bind_des之前一定不加冒号。

(12).描述选择表

用DESCRIBE SELECT

LIST语句描述选择描述区。

EXEC SQL DESCRIBE SELECT LIST FOR sql_stmt INTO select_des;

注意:DESCRIBE把F设置为该查询选择表项的实际个数,如果语句不是查询,则被设置为0。

此时NUMBER的长度仍然不能用,还需要用sqlprc()来分离精度和定标。

(13).重新设置选择表项的最大数

把选择表项的个数重新设置为DESCRIBE实际发现的个数。

select_stmt->N = select_stmt->F;

(14).重新设置选择表项的长度和数据类型

重新设置选择表项的长度和数据类型,以便显示它们。

如:

sqlnul(&(select_stmt->T[i]), &(select_stmt->T[i]), &nullok);

switch( select_stmt->T[i]) {

case 1: break;

case 2: sqlprc(&select_stmt->L[i], &prec, &scal);

if ( prec == 0 ) prec = 40;

select_des->L[i] = prec + 2;

if (scal < 0) select_des->L[i] += -scal;

break;

case 8: select_des->L[i] = 240;

break;

case 11:select_des->L[i] = 18;

break;

case 12: select_des->L[i] = 9;

break;

case 23: break;

case 24: select_des->L[i] = 240;

break;

}

select_stmt->V[i] = malloc(select_stmt->L[i]);

select_stmt->I[i] = (unsigned short *)malloc(sizeof(short));

if (select_stmt->T[i] != 24) select_stmt->T[i] = 1;

(15).从光标缓冲区中提取行

用FETCH把提取的行放入选择描述区所指向的数据缓冲区。

EXEC SQL FETCH emp_cursor USING DESCRIPTOR select_des;

在输出缓冲区中,对于数据类型1,ORACLE使用存放在L数组中的长度,左对齐CHAR和VARCHAR2数据,右对齐NUMBER数据。

(16).取和处理选择表项的值

处理FETCH所返回的选择表项。

(17).撤销存储分配

释放选择表项、虚拟输入宿主变量、指示器变量和描述区所用的空间。

使用free释放malloc分配的空间。

使用sqlclu()库函数撤销描述区本身的存储空间。

sqlclu(select_des);

sqlclu(bind_des);

(18).关闭光标

关闭光标。

EXEC SQL CLOSE emp_cursor;

9.关于游标的释放

在一个连接中,若该连接引用记数为1,则关闭该连接也释放游标;如在同一个进程中打开连接,操作数据,关闭连接。

若连接记数大于1,如父进程打开连接,子进程共享该连接进行操作,则连接记数大于1,子进程不能做关闭连接操作。此时要释放一个游标,在关闭游标后,还必须做commit或rollback;此外,还要设置release_cursor选项为yes,设置方法是在proc命令行中增加release_cursor=yes,或在程序中编写:

EXEC ORACLE OPTION(RELEASE_CURSOR=YES);

否则不能释放,最终会报-1000错:maximum open

cursors exceeded。

10.Pro*C命令选项

Pro*C的命令格式如下:

proc INAME=filename [Option_name1=value1 Option_name2=value2 … ]

注意:等号两侧不能有空格。

在程序中指定选项的格式如下:

EXEC SQL OPTION(option_name=value);

编译选项如下:

ASACC

ASACC=YES|NO;

缺省值为NO。指出清单文件是否为了回车控制而遵循使用每一行第一列的ASA约定。

注意:只能在命令行上输入。

CODE

CODE=ANSI_C|KR_C

缺省值为KR_C。产生的C函数原型的格式。

DBMS

DBMS=NATIVE|V6|V7

缺省值为NATIVE。指定所用的ORACLE数据库管理系统的版本,是6版、7版或本国版。

注意:只能在命令行上输入。

DEFINE

用于定义一个符号,用于进行条件编译。

如果在程序中输入时,使用如下语法:

EXEC ORACLE DEFINE symbol;

ERRORS

ERRORS=YES|NO;

缺省值为YES。指出预编译程序的错误信息是否被发送到终端和清单文件上,或仅仅给清单文件。

FIPS

FIPS=YES|NO;

缺省值为NO。当FIPS=YES时,如果使用一个ANSI

SQL的ORACLE扩展,或以不一致的方式使用一个ANSI SQL性能,就发出警告(不是错误)信息。

HOLD_CURSOR

HOLD_CURSOR=YES|NO;

缺省值为NO。

当执行SQL数据操纵语句时,其相关的光标被连到光标高速缓冲存储器中的一项上,该项又被依次连接到ORACLE专用的SQL区域上,该区域存储处理该语句所需的信息。

当HOLD_CURSOR=NO时,在ORACLE执行完SQL语句或关闭光标后,预编译程序直接撤去该链,释放分析块和分配给专用SQL区域的内存,并把该链标为可再使用。这时另一个SQL语句就又可使用该链来指向光标高速缓冲存储器的项了。

当HOLD_CURSOR=YES时,该链被保留,预编译程序不再使用它。这对经常使用的SQL语句是有用的。

注意:RELEASE_CURSOR=YES优先于HOLD_CURSOR=YES;HOLD_CURSOR=NO优先于RELEASE_CURSOR=NO。

HOST

HOST=C|COB74|COBOL|FORTRAN|PASCAL|PLI;

指出输入文件的宿主语言。

INCLUDE

INCLUDE=path;

缺省值为当前目录。指定EXEX SQL

INCLUDE文件的目录路径,它只适用于使用目录的操作系统。

IRECLEN

IRECLEN=length;

缺省值为80。指定输入文件的纪录长度。

注意:只能在命令行输入,指定的值不应超过ORECLEN的值。

LINES

LINES=YES|NO;

缺省值为NO。当LINES=YES时,预编译程序对输出文件加C预编译程序命令#line。为NO时不输出。

LNAME

LNAME=path and

filename;

缺省值为“输入文件.LIS”。为清单文件指定非缺省名。

注意:只能在命令行输入。

LRECLEN

LRECLEN=integer;

缺省值为132。指定清单文件的记录长度。

注意:只能在命令行输入。

LTYPE

LTYPE=LONG|SHORT|NONE;

缺省值为LONG。

指定清单类型。当LTYPE=LONG时,清单文件中包含输入行;当LTYPE=SHORT时,不包含输入行;当LTYPE=NONE时,不建立清单文件。

MAXLITERAL

MAXLITERAL=integer;

缺省值为1000(C语言)。指出预编译程序生成的串文字的最大长度。

MAXOPENCURSORS

MAXOPENCURSORS=integer;

缺省值为10。指定同时打开的光标数。每个用户处理能打开的光标的最大数由ORACLE初始化参数OPEN_CURSORS设置,其范围为5至255。该选项可指定一个较初始值小的值,必须比初始值至少低6。

MODE

MODE=ANSI|ISO|ANSI14|ISO14|ANSI13|ISO13|ORACLE;

缺省值为ORACLE。指定程序遵循的标准。

ONAME

ONAME=path and

filename;

指定输出文件名。

注意:只能在命令行上输入。

ORACA

ORACA=YES|NO;

缺省值为NO。指出程序能否使用ORACLE通讯区。

ORECLEN

ORECLEN=integer;

缺省值为80。指定输出文件的记录长度。

注意:只能在命令行输入,值应大于等于IRECLEN的值。

PAGELEN

PAGELEN=integer;

缺省值为66。指定清单文件的每一物理页的行数。

注意:只能在命令行上输入。

RELEASE_CURSOR

RELEASE_CURSOR=YES|NO;

缺省值为NO。

该选项用来控制光标和光标高速缓冲存储器之间的链。为了保证在关闭光标时使有关的资源被释放,必须指定:

RELEASE_CURSOR=YES。

相关描述见HOLD_CURSOR。

SELECT_ERROR

SELECT_ERROR=YES|NO。

缺省值为YES。

当SELECT_ERROR=YES时,若单行SELECT语句返回多于一行,或多行SELECT语句返回的行数比宿主数组能容纳的还要多,则产生错误,且查询的结果是不确定的。当指定SELECT_ERROR=NO时,则不产生错误。

SQLCHECK

SQLCHECK=SEMANTICS|FULL|SYNTAX|LIMITED|NONE;

缺省值为SYNTAX。指定语法和语义检查的类型和范围。

USERID

USERID=username/password;

指定ORACLE用户名和密码。

注意:只能在命令行上输入。

XREF

XREF=YES|NO;

缺省值为YES。指出是否在清单文件中列交叉索引表。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值