• 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

  • 相关阅读:
    Python的if判断与while循环
    python基础之数据类型与变量
    网络基础之网络协议篇
    操作系统简介
    计算机基础之计算机硬件系统
    从头开始编写一个Orchard网上商店模块(3)
    从头开始编写一个Orchard网上商店模块(2)
    从头开始编写一个Orchard网上商店模块(1)
    var和dynamic的区别及如何正确使用dynamic ?
    [DOM Event Learning] Section 3 jQuery事件处理基础 on(), off()和one()方法使用
  • 原文地址:https://www.cnblogs.com/diylab/p/1624528.html
Copyright © 2020-2023  润新知