sqlca\ oraca\指示器变量,保存了 sql 执行场景,为错误诊断和善后处理提供了方便。
sqlca 与 oraca 比较
1、
1、sqlca 程序级的,oraca 是数据库级的。一个程序有多个连接,则只有一个 sqlca,却可以有多个 oraca.
2、oraca 提供了比 sqlca 更丰富的诊断信息。(runtime errors and status changes )
3、oraca 会带来显著的性能下降。
Oracle Communications Area (ORACA)
结构:
{
char oracaid[8]; /* Reserved */
long oracabc; /* Reserved */
/* Flags which are setable by User. */
long oracchf; /* <> 0 if "check cur cache consistncy"*/
long oradbgf; /* <> 0 if "do DEBUG mode checking" */
long orahchf; /* <> 0 if "do Heap consistency check" */
long orastxtf; /* SQL stmt text flag */
#define ORASTFNON 0 /* = don't save text of SQL stmt */
#define ORASTFERR 1 /* = only save on SQLERROR */
#define ORASTFWRN 2 /* = only save on SQLWARNING/SQLERROR */
#define ORASTFANY 3 /* = always save */
struct
{
unsigned short orastxtl;
char orastxtc[70];
} orastxt; /* text of last SQL stmt */
struct
{
unsigned short orasfnml;
char orasfnmc[70];
} orasfnm; /* name of file containing SQL stmt */
long oraslnr; /* line nr-within-file of SQL stmt */
long orahoc; /* highest max open OraCurs requested */
long oramoc; /* max open OraCursors required */
long oracoc; /* current OraCursors open */
long oranor; /* nr of OraCursor re-assignments */
long oranpr; /* nr of parses */
long oranex; /* nr of executes */
};
重要的成员:
struct orasfnm; /* name of file containing SQL stmt */
long oraslnr; /* line nr-within-file of SQL stmt */
使用:
EXEC SQL INCLUDE ORACA;
EXEC ORACLE OPTION (ORACA=YES);
sqlca 可以用来识别 sql语句的执行结果,及详细的错误描述。

{
unsigned char sqlcaid[8];
long sqlabc;
long sqlcode;
short sqlerrml;
unsigned char sqlerrmc[10];
unsigned char sqlerrp[8];
long sqlerrd[6];
unsigned char sqlwarn[21];
unsigned char sqlstate[5];
}
sqlcaid:标识性域,包含字符串“sqlca”.
Sqlabc:包含sqlca结构的长度。
Sqlerrml:包含sqlerrmc域中数据的实际长度。
Sqlerrmc: 由0或多个字串组成,它对返回的值给以一个更详细的解释。如返回的代码表示表没找到,则此域中包含未找到的表名。
Sqlerrp: 包含一些对用户无用的论断信息。
Sqlstate: 长度为5的字符串,它指示SQL语句的查询结果。与sqlca不同的是,它遵循ANSI/ISOSQL92的标准,所以,尽管不同数据库产品的sqlca结构中sqlcode域的含义不同,但sqlstate域的含义是相同的。
重要的字段:
sqlerrd[4] This component holds an offset that specifies the character position at which a parse error begins in the most recently executed SQL statement. The first character occupies position zero.
当 sql 语句发生解析错误时,这个字段保存了 sql 语句发生错误的偏移。
SQLStmtGetText() 是 odbc 中用来获取最近执行的 sql 语句的函数。
sqlgls() 是嵌入式sql 中 用来获取最近执行的 sql 语句的函数。(#include <sqlcpr.h> ) 好像不总是有用?
可以用 SQLStmtGetText() 和 sqlgls() 获得 sql 操作的类型 ( function_type )。在一些数据库框架中,sql 是用户配置实现的,框架需要根据sql操作类型作为相应的分配 数据交换缓存 的决策,但不知道sql 操作类型。所以上面识别sql 操作类型的机制尤其有用。

* The sqlvcp.pc program demonstrates how you can use the
* sqlvcp() function to determine the actual size of a
* VARCHAR struct. The size is then used as an offset to
* increment a pointer that steps through an array of
* VARCHARs.
*
* This program also demonstrates the use of the sqlgls()
* function, to get the text of the last SQL statement executed.
* sqlgls() is described in the "Error Handling" chapter of
* The Programmer's Guide to the Oracle Pro*C/C++ Precompiler.
*/
#include <stdio.h>
#include <sqlca.h>
#include <sqlcpr.h>
/* Fake a VARCHAR pointer type. */
struct my_vc_ptr
{
unsigned short len;
unsigned char arr[32767];
};
/* Define a type for the VARCHAR pointer */
typedef struct my_vc_ptr my_vc_ptr;
my_vc_ptr *vc_ptr;
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR *names;
int limit; /* for use in FETCH FOR clause */
char *username = "scott/tiger";
EXEC SQL END DECLARE SECTION;
void sql_error();
extern void sqlvcp(), sqlgls();
main()
{
unsigned int vcplen, function_code, padlen, buflen;
int i;
char stmt_buf[120];
EXEC SQL WHENEVER SQLERROR DO sql_error();
EXEC SQL CONNECT :username;
printf("\nConnected.\n");
/* Find number of rows in table. */
EXEC SQL SELECT COUNT(*) INTO :limit FROM emp;
/* Declare a cursor for the FETCH statement. */
EXEC SQL DECLARE emp_name_cursor CURSOR FOR
SELECT ename FROM emp;
EXEC SQL FOR :limit OPEN emp_name_cursor;
/* Set the desired DATA length for the VARCHAR. */
vcplen = 10;
/* Use SQLVCP to help find the length to malloc. */
sqlvcp(&vcplen, &padlen);
printf("Actual array length of VARCHAR is %ld\n", padlen);
/* Allocate the names buffer for names.
Set the limit variable for the FOR clause. */
names = (VARCHAR *) malloc((sizeof (short) +
(int) padlen) * limit);
if (names == 0)
{
printf("Memory allocation error.\n");
exit(1);
}
/* Set the maximum lengths before the FETCH.
* Note the "trick" to get an effective VARCHAR *.
*/
for (vc_ptr = (my_vc_ptr *) names, i = 0; i < limit; i++)
{
vc_ptr->len = (short) padlen;
vc_ptr = (my_vc_ptr *)((char *) vc_ptr +
padlen + sizeof (short));
}
/* Execute the FETCH. */
EXEC SQL FOR :limit FETCH emp_name_cursor INTO :names;
/* Print the results. */
printf("Employee names--\n");
for (vc_ptr = (my_vc_ptr *) names, i = 0; i < limit; i++)
{
printf
("%.*s\t(%d)\n", vc_ptr->len, vc_ptr->arr, vc_ptr->len);
vc_ptr = (my_vc_ptr *)((char *) vc_ptr +
padlen + sizeof (short));
}
/* Get statistics about the most recent
* SQL statement using SQLGLS. Note that
* the most recent statement in this example
* is not a FETCH, but rather "SELECT ENAME FROM EMP"
* (the cursor).
*/
buflen = (long) sizeof (stmt_buf);
/* The returned value should be 1, indicating no error. */
sqlgls(stmt_buf, &buflen, &function_code);
if (buflen != 0)
{
/* Print out the SQL statement. */
printf("The SQL statement was--\n%.*s\n", buflen, stmt_buf);
/* Print the returned length. */
printf("The statement length is %ld\n", buflen);
/* Print the attributes. */
printf("The function code is %ld\n", function_code);
EXEC SQL COMMIT RELEASE;
exit(0);
}
else
{
printf("The SQLGLS function returned an error.\n");
EXEC SQL ROLLBACK RELEASE;
exit(1);
}
}
void
sql_error()
{
char err_msg[512];
int buf_len, msg_len;
EXEC SQL WHENEVER SQLERROR CONTINUE;
buf_len = sizeof (err_msg);
sqlglm(err_msg, &buf_len, &msg_len);
printf("%.*s\n", msg_len, err_msg);
EXEC SQL ROLLBACK RELEASE;
exit(1);
}
游标
cursor
SQL%ROWCOUNT
指示器变量:
1、用于指示某个输入字段可以为空。
2、用于指示某个输出字段为空或截断。
参考资料:
Embedded SQL (in C++)/Oracle
http://www.ugrad.cs.ubc.ca/~cs304/2005W1/tutorials/tutorials.html
Pro*C/C++ Precompiler Programmer's Guide
Release 9.2
http://download.oracle.com/docs/cd/B13789_01/appdev.101/a97269/toc.htm