分类: Oracle
2015-04-04 09:14:34
以下是正文
1.数组功能Proc中支持使用宿主变量数组一次查询SELECT/插入INSERT多条记录。在某些情况下非常有用,但不具有移植性。
当MODE={ANSI13|ORACLE}时,要求说明SQLCA,不说明将导致编译或连接错误。当MODE={ANSI|ANSI14}时,SQLCA的说明是可选的,但必须说明一个SQLCODE状态变量。
说明形式:
EXEC SQL INCLUDE sqlca;
当Proc源程序由多个文件组成时,sqlca说明在一个文件里,其他文件使用如下引用方式:
#define SQLCA_STORAGE_CLASS extern
可通过定义符号SQLCA_INIT来初始化SQLCA。
字段说明:
sqlglm函数说明如下:
sqlglm( message_buff, &buffer_size, &message_length );
其中,message_buff是文本缓冲区;
buffer_size存放缓冲区的长度,以字节为单位;
message_length是错误信息的实际长度。
ORACLE错误信息的最大长度是512字节。
形式1:
EXEC SQL CONNECT :username IDENTIFIED BY :password;
其中,username和password是CHAR或VARCHAR类型的宿主变量,分别包含用户名和密码。这里必须使用宿主变量,不能直接使用字符串。
形式二:
EXEC SQL CONNECT :user_pwd;
其中宿主变量user_pwd包含由字符’/’分隔的用户名和密码,即(username/password)。
形式三(自动登录):
char oracleid = ‘/’;
EXEC SQL CONNECT :oracleid;
使用用户名OPS$username登录,其中username是当前登录到操作系统上的用户名或任务名。
其中,db_name包含远程数据库名(对于oracle8i,就是在配置文件tnsnames.ora中定义的名称)。
可以为该连接定义一个连接名,db_link_name可以是一个标示符,或者是宿主变量。若为标示符,则需要使用DECLARE DATABAE进行说明。
若使用了AT子句,则在后面的SQL操作中也要指定该连接,否则操作的是缺省连接上的数据,而不是AT指定的连接。如:
EXEC SQL AT db_link_name SELECT…;
EXEC SQL AT db_link_name INSERT…;
EXEC SQL AT db_link_name UPDATE…;
EXEC SQL AT db_link_name DECLARE cursor_name CURSOR…;
不能在PREPARE、DESCRIBE、OPEN、FETCH、CLOSE中使用AT子句。
可以使用多条EXEC SQL CONNECT AT语句登录到多个数据库上,或为同一个数据库建立多个连接。
之后操作数据库对象时要指定链名:
EXEC SQL SELECT * FROM emp@link_name;
事务的结束有如下情况:
完成如下功能:
程序中必须用COMMIT/ROLLBACK RELEASE来显示结束最后一个事务并断开连接。
保留点用于部分回滚。
如果给两个保留点设置相同的名字,则前一个保留点被取消。每个用户会话期的活动保留点最大数为5(缺省值)。该值可修改配置文件init.ora中的SAVEPOINTS来改变,最大255。
完成如下功能:
完成如下功能:
当对该描述区进行分配时,函数sqlald()把数组元素V[0]~V[N-1]设置为0。
对于选择描述区,必须在发FETCH命令之前分配数据缓冲区和设置该数组。
对于结合缓冲区,必须在发OPEN命令之前设置该数组。
对于选择描述区,DESCRIBE SELECT LIST语句把长度数组设置为每一个选择表项所期望的最大数。
在FETCH之前必须把L[i]重新设置为所需要的数据缓冲区的长度。
对于结合缓冲区,在发OPEN命令之前,必须设置长度数组。
对于选择描述区,DESCRIBE SELECT LIST语句把数据类型代码数组设置为选择表项的内部数据类型(如CHAR、NUMBER或DATE)。
因为ORACLE数据类型的内部格式很难处理,所以在FETCH之前,可以设置某些数据类型。
T[i]的高位指出第i个选择表项的NULL/NOT NULL状态。在发OPEN或FETCH之前,一定要清除该位。用库函数sqlnull()来检索数据类型代码和清除NULL/NOT NULL位。
对于结合描述区,DESCRIBE BIND VARIABLES把数据类型代码的数组设置为0。在发OPEN之前,必须重新设置存储在每一个元素的数据类型代码。该代码表示V[i]所指向的数据缓冲区的外部(C)数据类型。
对于选择缓冲区,必须在发FETCH之前设置该地址数组。当ORACLE执行FETCH之后,如果第i个返回的选择表项值为NULL,那么I[i]所指向的那个指示器变量的值被置为-1,否则,它被置为0或一个正整数(值被截短)。
对于结合描述区,必须在发OPEN之前设置地址数组和相关的数据缓冲区。当ORACLE执行OPEN时,I[i]所指向的那个指示器变量的值决定第i个实输入宿主变量是否是一个NULL值。如果指示器变量的值为-1,则其相关实输入宿主变量的值为NULL。
使用sqlald()来分配该数据缓冲区,并把其地址存放在S数组中。
当分配一个描述区时,sqlald()设置该数组元素M[0]~M[N-1]。当对S[i]指向的数据缓冲区存储时,第i个名字被截成M[i]中的长度(如果有必要的话)。
DESCRIBE设置C[0]~C[N-1]。
用sqlald()来分配数据缓冲区并把它们的地址存储在X数组中。
DESCRIBE BIND VARIABLES指示ORALCE把第i个指示器变量的名字存储在X[i]所指向的数据缓冲区中。
其中:
max_vars:sqlda结构中要描述的选择表项或虚拟输入宿主变量的最大个数;
max_name:选择表项或虚拟输入宿主变量名字的最大长度;
max_ind_name:指示器变量名的最大长度。对于选择sqlda,该项设置为0。
一般用指针来引用sqlda。
对于结合缓冲区,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。
在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。
EXEC SQL BEGIN DECLARE SECTION
VARCHAR select_stmt[120];
EXEC SQL END DECLARE SECTION
EXEC SQL INCLUDE sqlda;
sqlda *select_des;
sqlda *bind_des;
使用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。
select_des->N = 3;
bind_des->N = 3;
strcpy(select_stmt.arr, “select … where …” );
select_stmt.len = strlen(select_stmt.arr);
EXEC SQL PREPARE sql_stmt FROM :select_stmt;
EXEC SQL DEACLARE emp_cursor CURSOR FOR sql_stmt;
注意:对于此种方法的动态sql语句(不只是查询语句),都必须说明一个光标,在非查询语句情况下,打开光标即执行该动态sql语句。
EXEC SQL DESCRIBE BIND VARIABLES FOR sql_stmt INTO bind_des;
注意:在bind_des之前一定不加冒号。
bind_des->N = bind_des->F;
如:
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;
EXEC SQL OPEN emp_cursor USING DESCRIPTOR bind_des;
注意:在bind_des之前一定不加冒号。
EXEC SQL DESCRIBE SELECT LIST FOR sql_stmt INTO select_des;
注意:DESCRIBE把F设置为该查询选择表项的实际个数,如果语句不是查询,则被设置为0。
此时NUMBER的长度仍然不能用,还需要用sqlprc()来分离精度和定标。
select_stmt->N = select_stmt->F;
如:
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;
EXEC SQL FETCH emp_cursor USING DESCRIPTOR select_des;
在输出缓冲区中,对于数据类型1,ORACLE使用存放在L数组中的长度,左对齐CHAR和VARCHAR2数据,右对齐NUMBER数据。
使用free释放malloc分配的空间。
使用sqlclu()库函数撤销描述区本身的存储空间。
sqlclu(select_des);
sqlclu(bind_des);
EXEC SQL CLOSE emp_cursor;
若连接记数大于1,如父进程打开连接,子进程共享该连接进行操作,则连接记数大于1,子进程不能做关闭连接操作。此 时要释放一个游标,在关闭游标后,还必须做commit或rollback;此外,还要设置release_cursor选项为yes,设置方法是在 proc命令行中增加release_cursor=yes,或在程序中编写:
EXEC ORACLE OPTION(RELEASE_CURSOR=YES);
否则不能释放,最终会报-1000错:maximum open cursors exceeded。
注意:等号两侧不能有空格。
在程序中指定选项的格式如下:
EXEC SQL OPTION(option_name=value);
编译选项如下:
缺省值为NO。指出清单文件是否为了回车控制而遵循使用每一行第一列的ASA约定。
注意:只能在命令行上输入。
缺省值为KR_C。产生的C函数原型的格式。
缺省值为NATIVE。指定所用的ORACLE数据库管理系统的版本,是6版、7版或本国版。
注意:只能在命令行上输入。
如果在程序中输入时,使用如下语法:
EXEC ORACLE DEFINE symbol;
缺省值为NO。当FIPS=YES时,如果使用一个ANSI SQL的ORACLE扩展,或以不一致的方式使用一个ANSI SQL性能,就发出警告(不是错误)信息。
缺省值为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。
指出输入文件的宿主语言。
缺省值为当前目录。指定EXEX SQL INCLUDE文件的目录路径,它只适用于使用目录的操作系统。
缺省值为80。指定输入文件的纪录长度。
注意:只能在命令行输入,指定的值不应超过ORECLEN的值。
缺省值为NO。当LINES=YES时,预编译程序对输出文件加C预编译程序命令#line。为NO时不输出。
缺省值为“输入文件.LIS”。为清单文件指定非缺省名。
注意:只能在命令行输入。
缺省值为132。指定清单文件的记录长度。
注意:只能在命令行输入。
缺省值为LONG。
指定清单类型。当LTYPE=LONG时,清单文件中包含输入行;当LTYPE=SHORT时,不包含输入行;当LTYPE=NONE时,不建立清单文件。
缺省值为1000(C语言)。指出预编译程序生成的串文字的最大长度。
缺省值为10。指定同时打开的光标数。每个用户处理能打开的光标的最大数由ORACLE初始化参数OPEN_CURSORS设置,其范围为5至255。该选项可指定一个较初始值小的值,必须比初始值至少低6。
缺省值为ORACLE。指定程序遵循的标准。
指定输出文件名。
注意:只能在命令行上输入。
缺省值为NO。指出程序能否使用ORACLE通讯区。
缺省值为80。指定输出文件的记录长度。
注意:只能在命令行输入,值应大于等于IRECLEN的值。
缺省值为66。指定清单文件的每一物理页的行数。
注意:只能在命令行上输入。
缺省值为NO。
该选项用来控制光标和光标高速缓冲存储器之间的链。为了保证在关闭光标时使有关的资源被释放,必须指定:
RELEASE_CURSOR=YES。
相关描述见HOLD_CURSOR。
缺省值为YES。
当SELECT_ERROR=YES时,若单行SELECT语句返回多于一行,或多行SELECT语句返回的行数比宿主数组能容纳的还要多,则产生错误,且查询的结果是不确定的。当指定SELECT_ERROR=NO时,则不产生错误。
缺省值为SYNTAX。指定语法和语义检查的类型和范围。
指定ORACLE用户名和密码。
注意:只能在命令行上输入。
缺省值为YES。指出是否在清单文件中列交叉索引表。