这是我的页面头部

sql 善后处理的一些代码

 

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)

结构:

oraca 结构描述 定义于 oraca.h 中 
struct    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语句的执行结果,及详细的错误描述。

sqlca结构描述,定义于 sqlca.h 中  
struc sqlca
{
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); 

在pro c/c++ 和 odbc 编程中,经常在sql 语句中的某些字段值进行“绑定”。

 

游标

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

 

http://www.lslnet.com/linux/f/docs1/i26/big5217412.htm

posted @ 2009-12-15 10:27  范晨鹏  阅读(1261)  评论(0编辑  收藏  举报