标签:des io ar os 使用 for sp strong 文件
Proc也就是嵌入式C,与informix的ESQ/C有类似之处,本部分主要列出Proc与Esql的区别,相同部分请参见informix部分。
1.数组功能
Proc中支持使用宿主变量数组一次查询SELECT/插入INSERT多条记录。在某些情况下非常有用,但不具有移植性。
2.sqlca通讯区结构
struct sqlca { char sqlcaid[8]; long sqlabc; long sqlcode; struct { unsigned short sqlerrml; char sqlerrmc[70]; } sqlerrm; char sqlerrp[8]; long sqlerrd[6]; char sqlwarn[8]; char sqlext[8]; };
当MODE={ANSI13|ORACLE}时,要求说明SQLCA,不说明将导致编译或连接错误。当MODE={ANSI|ANSI14}时,SQLCA的说明是可选的,但必须说明一个SQLCODE状态变量。
说明形式:
EXEC SQL INCLUDE sqlca;
当Proc源程序由多个文件组成时,sqlca说明在一个文件里,其他文件使用如下引用方式:
#define SQLCA_STORAGE_CLASS extern
可通过定义符号SQLCA_INIT来初始化SQLCA。
字段说明:
初始化为sqlca,用于标示一个SQL通讯区。
保存SQL通讯区的长度,以字节为单位。
最近执行的SQL语句的状态。有以下值:
在Oracle中,“记录没有找到”的错误码有两个:在ANSI模式下是100,在Oracle模式下是1403。
保存sqlerrm.sqlerrmc中信息文本的长度。
保存与sqlcode相对应的错误信息文本,最长不超过70个字符。要获得超过70个字符的完整信息,需要使用sqlglm()函数。
sqlglm函数说明如下:
sqlglm( message_buff, &buffer_size, &message_length );
其中,message_buff是文本缓冲区;
buffer_size存放缓冲区的长度,以字节为单位;
message_length是错误信息的实际长度。
ORACLE错误信息的最大长度是512字节。
保留,未使用。
sqlerrd[0]:保留;
sqlerrd[1]:保留;
sqlerrd[2]:保存当前sql语句处理的行数。当语句处理失败时,该值无定义,当处理过程中出错时,则该值为成功处理的记录数;
sqlerrd[3]:保留;
sqlerrd[4]:保存相对位移,指出在哪个字符位置开始出现(语法)分析错误。第一个字符的相对位移是0;
sqlerrd[5]:保留。
有8个元素,当有警告发生时,相应元素被设置位‘W‘。
sqlwarn[0]:如果其他标志被设置,则其也被设置。若其为空,则表示其他7个全部没有设置;
sqlwarn[1]:如果字符数据输出到宿主变量时被截断,则设置该标志,对于数字数据被截断并不设置该标志。为了检查具体的截断情况,可查看宿主变量对应的指示变量,指示变量的值是列的原始长度。
sqlwarn[2]:未使用;
sqlwarn[3]:如果查询选择的列数不等于宿主变量的个数,则设置该标志;
sqlwarn[4]:如果DELETE和UPDATE语句没有WHERE子句,则设置该标志;
sqlwarn[5]:当执行CREATE语句由于PL/SQL编译错误失败时,设置该标志;
sqlwarn[6]:未使用;
sqlwarn[7]:未使用。
保留。
3.登录数据库
有如下三种形式:
形式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是当前登录到操作系统上的用户名或任务名。
[ EXEC SQL DECLARE db_link_name DATABASE; ] EXEC SQL CONNECT :username IDENTIFIED BY :password [ AT db_link_name ] USING :db_name;
其中,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 CREATE DATABASE LINK link_name CONNECT TO username IDENTIFIED BY password USING db_name;
之后操作数据库对象时要指定链名:
EXEC SQL SELECT * FROM emp@link_name;
Oracle中不支持滚动游标。
Oracle中没有BEGIN WORK之类的事务开始语句,程序中的第一个SQL语句(非CONNECT语句)自动开始一个事务。
事务的结束有如下情况:
EXEC SQL [ AT :link_name ] COMMIT WORK [ RELEASE ];
完成如下功能:
使用RELEASE除了完成上述功能外,还释放所有资源并切断与ORACLE的连接。
程序中必须用COMMIT/ROLLBACK RELEASE来显示结束最后一个事务并断开连接。
事务保留点是事务内的标志点,建立方法如下:
EXEC SQL [ AT link_name ] SAVEPOINT savepoint_name;
保留点用于部分回滚。
如果给两个保留点设置相同的名字,则前一个保留点被取消。每个用户会话期的活动保留点最大数为5(缺省值)。该值可修改配置文件init.ora中的SAVEPOINTS来改变,最大255。
事务级回滚:
EXEC SQL [ AT link_name ] ROLLBACK WORK [ RELEASE ];
完成如下功能:
部分事务回滚:
EXEC SQL [ AT link_name ] ROLLBACK WORK TO \ SAVEPOINT savepoint_name;
完成如下功能:
如果执行一条SQL语句失败,ORACLE会自动将其回滚,并在sqlca.sqlcode中返回一个错误码。
结构构成:
struct SQLDA { int N; char **V; int *L; short *T; short **I; int F; char **S; short *M; short *C; char **X; short *Y; short *Z; };
指定要描述的选择表项或虚拟输入宿主变量的最大个数。N确定了描述区中数组的元素个数。在发出DESCRIBE命令之前,必须用库函数sqlald()把N设置为描述区中数组的维数。在DESCRIBE之后,必须再把N设置为所描述的选择表项或虚拟输入宿主变量的实际个数,该数据被存储在F变量中。
V是一个数组指针,其元素分别指向缓冲区中存储的每一个选择表项或实输入宿主变量值。
当对该描述区进行分配时,函数sqlald()把数组元素V[0]~V[N-1]设置为0。
对于选择描述区,必须在发FETCH命令之前分配数据缓冲区和设置该数组。
对于结合缓冲区,必须在发OPEN命令之前设置该数组。
L是一个指针,它指向一个数组,该数组包含存储在数据缓冲区中的选择表项或实输入宿主变量的长度。
对于选择描述区,DESCRIBE SELECT LIST语句把长度数组设置为每一个选择表项所期望的最大数。
在FETCH之前必须把L[i]重新设置为所需要的数据缓冲区的长度。
对于结合缓冲区,在发OPEN命令之前,必须设置长度数组。
T是一个指针,它指向一个数组,该数组存放选择表项或实输入宿主变量的数据类型代码。
对于选择描述区,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)数据类型。
I是一个数组指针,其元素分别指向数据缓冲区中每一个指示器变量的值。必须设置元素I[0]~I[N-1]。
对于选择缓冲区,必须在发FETCH之前设置该地址数组。当ORACLE执行FETCH之后,如果第i个返回的选择表项值为NULL,那么I[i]所指向的那个指示器变量的值被置为-1,否则,它被置为0或一个正整数(值被截短)。
对于结合描述区,必须在发OPEN之前设置地址数组和相关的数据缓冲区。当ORACLE执行OPEN时,I[i]所指向的那个指示器变量的值决定第i个实输入宿主变量是否是一个NULL值。如果指示器变量的值为-1,则其相关实输入宿主变量的值为NULL。
F是DESCRIBE所发现的选择表项或虚拟输入宿主变量的实际个数。因此,F是由DESCRIBE来设置。如果F<0,则表示DESCRIBE发现了过多的选择表项或虚拟输入宿主变量(相对于N变量),F的绝对值就是实际个数。
S是一个数组指针,其元素分别指向数据缓冲区中所存储的每一个选择表项或虚拟输入宿主变量的名字。
使用sqlald()来分配该数据缓冲区,并把其地址存放在S数组中。
M是一个指针,它指向一个数组,该数组存放缓冲区中所包含的选择表项或虚拟输入宿主变量名字最大长度。这些缓冲区由S数组元素寻址。
当分配一个描述区时,sqlald()设置该数组元素M[0]~M[N-1]。当对S[i]指向的数据缓冲区存储时,第i个名字被截成M[i]中的长度(如果有必要的话)。
C指向一个数组,该数组元素包含选择表项或虚拟输入宿主变量名字的当前长度。
DESCRIBE设置C[0]~C[N-1]。
X是一个数组指针,其元素分别指向数据缓冲区中所存储的每一个指示器变量的名字。只能把指示器变量的名字与实输入宿主变量联系起来,因此,X只适用于结合缓冲区。
用sqlald()来分配数据缓冲区并把它们的地址存储在X数组中。
DESCRIBE BIND VARIABLES指示ORALCE把第i个指示器变量的名字存储在X[i]所指向的数据缓冲区中。
Y指向一个数组,该数组的元素分别包含每一个指示器变量名字的最大长度。Y也只适用于结合缓冲区。
Z指向一个数组,该数组的元素分别包含当前每一个指示器变量名字的最大长度。Z也只适用于结合缓冲区。
EXEC SQL INCLUDE sqlda; sqlda *bind_dp; bind_dp = sqlald( … );
sqlald函数为sqlda结构分配空间。函数格式如下:
descriptor_name = sqlald(max_vars, max_name, max_ind_name );
其中:
max_vars:sqlda结构中要描述的选择表项或虚拟输入宿主变量的最大个数;
max_name:选择表项或虚拟输入宿主变量名字的最大长度;
max_ind_name:指示器变量名的最大长度。对于选择sqlda,该项设置为0。
一般用指针来引用sqlda。
对于选择描述区,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。
对于每一个选择表列(不是表达式),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。
在说明段说明一个串型的宿主变量,以保存查询语句的文本。
EXEC SQL BEGIN DECLARE SECTION VARCHAR select_stmt[120]; EXEC SQL END DECLARE SECTION
说明选择和结合SQLDA。
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。
设置能被DESCRIBE的选择表项和虚拟输入宿主变量的最大个数。
select_des->N = 3; bind_des->N = 3;
把查询语句文本存放在串型宿主变量中。
strcpy(select_stmt.arr, “select … where …” ); select_stmt.len = strlen(select_stmt.arr);
PREPARE宿主串中的查询语句。
EXEC SQL PREPARE sql_stmt FROM :select_stmt;
DECLARE一个查询光标。
EXEC SQL DEACLARE emp_cursor CURSOR FOR sql_stmt;
注意:对于此种方法的动态sql语句(不只是查询语句),都必须说明一个光标,在非查询语句情况下,打开光标即执行该动态sql语句。
把实输入宿主变量DESCRIBE进结合描述区中。
EXEC SQL DESCRIBE BIND VARIABLES FOR sql_stmt INTO bind_des;
注意:在bind_des之前一定不加冒号。
把虚拟输入宿主变量的个数重新设置为DESCRIBE实际发现的个数。
bind_des->N = bind_des->F;
为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;
用OPEN…USING打开与结合描述区相对应的光标。
EXEC SQL OPEN emp_cursor USING DESCRIPTOR bind_des;
注意:在bind_des之前一定不加冒号。
用DESCRIBE SELECT LIST语句描述选择描述区。
EXEC SQL DESCRIBE SELECT LIST FOR sql_stmt INTO select_des;
注意:DESCRIBE把F设置为该查询选择表项的实际个数,如果语句不是查询,则被设置为0。
此时NUMBER的长度仍然不能用,还需要用sqlprc()来分离精度和定标。
把选择表项的个数重新设置为DESCRIBE实际发现的个数。
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;
用FETCH把提取的行放入选择描述区所指向的数据缓冲区。
EXEC SQL FETCH emp_cursor USING DESCRIPTOR select_des;
在输出缓冲区中,对于数据类型1,ORACLE使用存放在L数组中的长度,左对齐CHAR和VARCHAR2数据,右对齐NUMBER数据。
处理FETCH所返回的选择表项。
释放选择表项、虚拟输入宿主变量、指示器变量和描述区所用的空间。
使用free释放malloc分配的空间。
使用sqlclu()库函数撤销描述区本身的存储空间。
sqlclu(select_des); sqlclu(bind_des);
关闭光标。
EXEC SQL CLOSE emp_cursor;
在一个连接中,若该连接引用记数为1,则关闭该连接也释放游标;如在同一个进程中打开连接,操作数据,关闭连接。
若连接记数大于1,如父进程打开连接,子进程共享该连接进行操作,则连接记数大于1,子进程不能做关闭连接操作。此时要释放一个游标,在关闭游标后,还必须做commit或rollback;此外,还要设置release_cursor选项为yes,设置方法是在proc命令行中增加release_cursor=yes,或在程序中编写:
EXEC ORACLE OPTION(RELEASE_CURSOR=YES);
否则不能释放,最终会报-1000错:maximum open cursors exceeded。
Pro*C的命令格式如下:
proc INAME=filename [Option_name1=value1 Option_name2=value2 … ]
注意:等号两侧不能有空格。
在程序中指定选项的格式如下:
EXEC SQL OPTION(option_name=value);
编译选项如下:
ASACC=YES|NO;
缺省值为NO。指出清单文件是否为了回车控制而遵循使用每一行第一列的ASA约定。
注意:只能在命令行上输入。
CODE=ANSI_C|KR_C
缺省值为KR_C。产生的C函数原型的格式。
DBMS=NATIVE|V6|V7
缺省值为NATIVE。指定所用的ORACLE数据库管理系统的版本,是6版、7版或本国版。
注意:只能在命令行上输入。
用于定义一个符号,用于进行条件编译。
如果在程序中输入时,使用如下语法:
EXEC ORACLE DEFINE symbol;
ERRORS=YES|NO;
缺省值为YES。指出预编译程序的错误信息是否被发送到终端和清单文件上,或仅仅给清单文件。
FIPS=YES|NO;
缺省值为NO。当FIPS=YES时,如果使用一个ANSI SQL的ORACLE扩展,或以不一致的方式使用一个ANSI SQL性能,就发出警告(不是错误)信息。
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=C|COB74|COBOL|FORTRAN|PASCAL|PLI;
指出输入文件的宿主语言。
INCLUDE=path;
缺省值为当前目录。指定EXEX SQL INCLUDE文件的目录路径,它只适用于使用目录的操作系统。
IRECLEN=length;
缺省值为80。指定输入文件的纪录长度。
注意:只能在命令行输入,指定的值不应超过ORECLEN的值。
LINES=YES|NO;
缺省值为NO。当LINES=YES时,预编译程序对输出文件加C预编译程序命令#line。为NO时不输出。
LNAME=path and filename;
缺省值为“输入文件.LIS”。为清单文件指定非缺省名。
注意:只能在命令行输入。
LRECLEN=integer;
缺省值为132。指定清单文件的记录长度。
注意:只能在命令行输入。
LTYPE=LONG|SHORT|NONE;
缺省值为LONG。
指定清单类型。当LTYPE=LONG时,清单文件中包含输入行;当LTYPE=SHORT时,不包含输入行;当LTYPE=NONE时,不建立清单文件。
MAXLITERAL=integer;
缺省值为1000(C语言)。指出预编译程序生成的串文字的最大长度。
MAXOPENCURSORS=integer;
缺省值为10。指定同时打开的光标数。每个用户处理能打开的光标的最大数由ORACLE初始化参数OPEN_CURSORS设置,其范围为5至255。该选项可指定一个较初始值小的值,必须比初始值至少低6。
MODE=ANSI|ISO|ANSI14|ISO14|ANSI13|ISO13|ORACLE;
缺省值为ORACLE。指定程序遵循的标准。
ONAME=path and filename;
指定输出文件名。
注意:只能在命令行上输入。
ORACA=YES|NO;
缺省值为NO。指出程序能否使用ORACLE通讯区。
ORECLEN=integer;
缺省值为80。指定输出文件的记录长度。
注意:只能在命令行输入,值应大于等于IRECLEN的值。
PAGELEN=integer;
缺省值为66。指定清单文件的每一物理页的行数。
注意:只能在命令行上输入。
RELEASE_CURSOR=YES|NO;
缺省值为NO。
该选项用来控制光标和光标高速缓冲存储器之间的链。为了保证在关闭光标时使有关的资源被释放,必须指定:
RELEASE_CURSOR=YES。
相关描述见HOLD_CURSOR。
SELECT_ERROR=YES|NO。
缺省值为YES。
当SELECT_ERROR=YES时,若单行SELECT语句返回多于一行,或多行SELECT语句返回的行数比宿主数组能容纳的还要多,则产生错误,且查询的结果是不确定的。当指定SELECT_ERROR=NO时,则不产生错误。
SQLCHECK=SEMANTICS|FULL|SYNTAX|LIMITED|NONE;
缺省值为SYNTAX。指定语法和语义检查的类型和范围。
USERID=username/password;
指定ORACLE用户名和密码。
注意:只能在命令行上输入。
XREF=YES|NO;
缺省值为YES。指出是否在清单文件中列交叉索引表。
标签:des io ar os 使用 for sp strong 文件
原文地址:http://www.cnblogs.com/sherlockhomles/p/4072956.html