• Pro*C基础


    SQL变量的申明:
    
    EXEC SQL BEGIN DECLARE SECTION;
    
        类型  变量名【长度】
        varchar2  serv_number[11];
        其中可以定义C变量
    EXEC SQL END DECLARE SECTION;
    
    EXEC SQL INCLUDE Slqca;
    
    说明SQL的通讯区,记录执行每一个SQL语句的状态。
    
    错误信息处理
    
    EXEC SQL WHENEVER SQLERROR DO sqlerror(); 指出执行SQL语句时,如果发生错误应如何处理。
    
    
    连接数据库
    
    EXEC SQL CONNECT :username IDENTIFIED BY :password;
    
    
    
    嵌入式SQL语句或pl/sql块中的关键字应大写。
    
    
    
    SQL变量
    
    在变量的申明中定义,只允许包含下列语句:
    (一)SQL变量的类型说明语句
    (二)EXEC SQL INCLUDE 
    (三)EXEC SQL VAR
    (四)EXEC SQL TYPE
    
    
    EXEC SQL VAR 和EXEC SQL TYPE 分别用于将sql变量和外部的变量等价。用法如下:
    
    EXEC SQL VAR host_variable IS type_name[(length)];
    
    可以用户定义类型和等价:
    
    struct screen {
      
         short len;
         char buff[100];
    }
    typedef struct screen graphics;
    
    EXEC SQL BEGIN DECLARE SECTION;
    
    EXEC SQL TYPE graphics IS VARRAW(4000);
    
    EXEC SQL END DECLARE SECTION;
    
    可以将一个用户说明的类型定义为显示的或隐式的指针,然后使用新的类型。必须使用Reference;
    
    如:
        EXEC SQL TYPE graphics varraw(4000) Reference;
        graphics my_raw;
    
    可以使用如下的修饰符来说明变量的性质:
    
    auto 
    static
    extern 
    const   定义的常量
    volatile 有一个程序不知道的方法(如 通过设备)来改变值
    
    
    VARCHAR变量的说明和应用:
    
    C中没有这种类型,特别引入的这种类型,称为伪类型。
    
    EXEC SQL BEGIN DECLARE SECTION;
    
    VARCHAR  user_name(11);
    
    EXEC SQL END DECLARE SECTION;
    
    在预编译时,该变量被翻译成:
    
    struct {
    
    unsigned short len;
    unsigned char arr[20];
    } user_name;
    
    
    
    通讯区的说明:
    
    Oracle提供了两个通讯区SQL通讯区(sqlca)和Oracle通讯区(oraca)
    
    sqlca是一个结构类型的标量,是Oracle和应用程序的接口,执行Pro*C时,Oracle把每一个嵌入的SQL执行的状态存入sqlca;
    
    sqlca的结构:
    
    struct sqlca{
    
    char sqlcaid[8];     //标识一个sql通讯区
    long sqlbc;          //通讯区的长度
    long sqlcode;       
     /*
      最近执行Sql后的状态码
     有三中可能的值:
     0  正确结束
     >0 Oracle执行了该语句,但遇到了例外
     <0 Oracle未执行该语句,当出现这类错误时,应该回滚该事务。
     */
    struct {
    
      unsigned short sqlerrml;   //保存sqlerrmc中的文本的长度
      unsigned char  sqlerrmc[70]; //保存sqlcode编码对于的错误信息,只有当sqlcode的值为负时,才应用sqlerrmc,只有70个字符,如果要应用超过70个字符的信息,必须使用SQLGLM()函数。如果sqlcode执行为0时,sqlerrmc为最近sql的信息。
    }sqlerrm;
    
    char sqlerrp[8];
    long sqlerrd[6];
    char sqlwarn[8];
    char sqlext[8];
    } sqlca;
    
    
    通讯区的应用方式:
    
    EXEC SQL INCLUDE sqlca;
    
    或将上述编码拷贝到C代码中。
    
    SQLGLM的应用,sqlglm(message_buffer,&buffer_size,&message_length);
    
    message_buffer: 文本缓冲区,将错误的信息保留中这里,用空格补充后面的空间。
    buffer_size : 缓冲区的长度。
    message_length: Oracle错误信息的实际的长度。
    
    oraca
    
    类似与sqlca,但比sqlca提供的信息更多。
    
    INCLUDE 语句
    
    作用将一个文件拷贝到程序中,类似于#include
    
    定义:  EXEC SQL INCLUDE filename; 程序中使用的是filename的副本。
    
    
    断开数据库连接
    
    EXEC SQL COMMIT WORK RELEASE;
    
    错误处理的方法:
    
    EXEC SQL WHENERVE SQLERROR GOTO sqlerror;
    
    sqlerror:
    
        EXEC SQL WHENERVER SQLERROR CONTINUE;
    
        EXEC SQL ROLLBACK;
       
        exit(1);
    
    也可以使用方法: sqlerror();
    
    void sqlerror;
    
    EXEC SQL WHENEVER SQLERROR DO sqlerror();
    
    void sqlerror()
    {
       EXEC SQL WHENERVER SQLERROR CONTINUE;
    
        EXEC SQL ROLLBACK;
       
        exit(1);
     
    }
    
    数据未找到信息的处理方法:
    
    EXEC SQL WHENEVER  NOT FOUND GOTO notfound;
    
    notfound :
    
       printf("not found");
    
    SQLCA.SQLERRD[2]  //记录处理的行数
    
    select 语句中不允许使用FOR子句。
    
    select返回的多行确定时,可以使用数组,但必须有MODE={ANSI|ANSI13|ORACLE};
    
    当select返回的行不确定时,可以使用光标。
    
    光标的思想:
    
        使用光标时,开辟了一个缓冲区,将SELECT的查询结果存放在缓冲区中,并将指针指向第一条记录。
    
    光标语句的使用:
    
    (一)说明一个游标
    
         使用declare cursor
    
         EXEC SQL DECLARE emp_cursor CURSOR FOR
    
              SELECT BRAND_ID,BRAND_DESC 
              FROM TB_DET_BRAND
              WHERE BRAND_ALL_ID=:emp_number;
    
    注意:光标的全程必须在一个编译区内。
    
    (二)打开光标
    
         EXEC SQL OPEN emp_cursor;
     
        OPEN语句的作用:
     
         1. 定义一个光标缓冲区
         2. 把满足条件的行检索到缓冲区中
         3. 将光标指向第一行
         4. 行计算器sqlca.sqlerrd[2]清0;
    
    (三)提取
    
         EXEC SQL FETCH emp_cursor INTO :brand,:brand_name;
    
    (四)关闭光标
    
         EXEC SQL CLOSE emp_cursor;
    
    
    技巧: Oracle中的字符串以NULL结尾。因而,可以使用类型等价实现。
    
    typedef char aciz;
    
    aciz name;
    aciz brand;
    
    EXEC SQL TYPE aciz IS SRTING(20);
    
    这样,aciz是以NULL为结束符。
    
    光标使用的例子:
    
    main()
    {
         .......
    
     EXEC SQL WHENEVER SQLERROR DO sqlerror();
    
         //连接数据库
            EXEC SQL DECLARE emp_cursor CURSOR FOR
    
              SELECT BRAND_ID,BRAND_DESC 
              FROM TB_DET_BRAND
              WHERE BRAND_ALL_ID=:emp_number;
    
         EXEC SQL OPEN emp_cursor;
    
         for(;;)
         {
            EXEC SQL WHENEVER NOT FOUND DO break;
    
            EXEC SQL FECTH emp_cursor INTO  :brand,:brand_name;
    
             //处理信息 
            }
     
        EXEC SQL CLOSE emp_cursor;
        
        exit(0);
    }
    
    Pro*C嵌入PL/SQL块
    
    认为特色的地方:
    
    可以使用RECODE类型
    
    TYPE test_type IS RECODE
          ( brand_id varchar2(4) not null,
            brand_desc varchar2(80));
    
    嵌入PL/SQL的方法
    
    EXEC SQL EXECUTE 
         DECLARE    ---pl/SQL
         BEGIN
         END;
    END_EXEC;
    
    指示器变量:
    
    作用:
      从宿主程序接收NULL值存入数据库表中
      把NUll或截断的值输出给宿主变量
    
    使用方法:  如 :emp_name:ind_emp
    
    过程:
        当进入PL/SQL块时,如果指示器的值为-1,则PL/SQL自动把NULL值赋给相应的宿主变量。
        退出该块时,如果宿主变量的值为NULL,则把-1赋给相应的指示器变量。
    
    PL/SQL块中只使用数组的一部分时,可以指定最小的数组的大小:
    
    方法:  
          EXEC SQL ARRAYLEN host_array (array_integer);
    
    EXEC SQL BEGIN DECLARE SECTION;
    
       float salary[100];
       int m;
       EXEC SQL ARRAYLEN salary(m);
    EXEC SQL END DECLARE SECTION;
    
    指定数据的维数   m=30;
    上例中只有30个元素被传递到PL/SQL块中。
    
    方法:
    (一)启动oracle通讯区
    
         EXEC ORACLE OPTION (ORACA=YES);
    
    (二)指定RELEASE_CURSOR=YES,用于释放Pro*C执行后SQL的资源,这将保证数据操作后,oracle不保持表分析锁,后续的数据定义操作不会导致分析锁错误。
    
        EXEC ORACLE OPTION (RELEASE_CURSOR=YES);
    
    错误处理
    
    
    动态SQL技术
    
     动态sql方法1:  用于非select语句,方法: execute immedite ‘insert into ....’;不允许输入宿主变量;
      
      动态sql方法2:(用于非SELECT)
    
     PREPARE语句:(分析和命名一个动态SQL语句)
    
    EXEC SQL PREPARE [statement_name][block_name] FROM [:host_string][string_literal];
    
    例:
         strcpy(sql_t1,"DELETE FROM EMP WHERE EMP_NAME=:V");
    
         EXEC SQL PREPARE p1 FROM :sql_t1;
    
    EXECUTE 语句:
                
    例 EXEC SQL EXECUTE p1 USING :ind_emp;
    
    方法1和方法2区别: 方法1每执行一次分析一次,而方法二分析一次,多次执行。
    
    
     动态SQL方法3:(只用于select语句)
    
    例:
          EXEC SQL BEGIN DECLARE SECTION;
    
                  VARCHAR sqlstmt[80];
                  int imp;
                  int brand;
                  int brand_a;
          EXEC SQL END DECLARE SECTION;
    
    ....
         main()
    {
             //构造动态SQL
             sqlstmt.len=sprintf(sqlstmt.arr,"select brand_id,brand_all_id from tb_det_brand where brand_all_id=:v");
    
           //分析动态的SQL
           EXEC SQL PREPARE p1 FROM :sqlstmt;
            
           //说明光标
           EXEC SQL DECLARE c1 CURSOR FOR p1;
    
           imp=1001;
           ......
           //打开光标
           
           EXEC SQL OPEN c1 USING :imp;
    
           EXEC SQL WHENEVER  NOT FOUND DO break;
    
           while(true)
           {
                 //提取数据
                EXEC SQL FETCH c1 INTO :brand,:brand_a;
                ................
    
             }
        
           //关闭光标
           EXEC SQL CLOSE c1;
    
    }
    
    动态方法四:
    
    特点: 在执行SQL之前,表项、宿主变量个数、类型直到执行前仍然不知道。因而,不能在预编译时产生完整的Oracle调用。
    
    对于方法四,要求提供如下的信息:
    
        选择表项和实宿主变量的个数。
        每一个表项和实宿主变量的长途。
        每一个表项和实宿主变量的类型。
        每一个输出宿主变量(存储选择表项的值)和实输入宿主变量的内存单元地址。
    
    提供信息的方法:
    
    oracle提供的SQL的描述区来说明,它提供了一个sqlda 的数据结构。
    具体的过程如下:
    
         将选择表项和虚拟输入宿主变量分别保存在选择SQLDA和结合SQLDA中。选择表项的值和名字被存储在输出缓冲区,而实输入宿主变量的值和名字被存储在输入缓冲区。输出缓冲区的地址存储在选择SQLDA中,而输入缓冲区的地址存储在结合SQLDA中。
    
    SQLDA写入信息的方法:
    
    (一)sqlald()函数
        
         在分配描述区和缓冲区时,还把SLI(选择表项)或P(虚拟输入宿主变量)的名字在缓冲区中的地址和长度写入SQLDA中。
    
    (二)应用程序
    
         通过程序把存放SLI或BV(结合变量或实输入宿主标量)的值的缓冲区的地址、长度及数据类型写入SQLDA中。
    
    (三)DESCRIBE
    
         DESCRIBE SELECT LIST 检查每一个选择表项的信息将信息存储在选择SQLDA及输出缓冲区中。
         
         DESCRIBE BIND VARIABLES 检查每一个虚拟输入宿主变量的信息将信息存储在结合SQLDA及输入缓冲区中。
    
    SQLDA的说明和应用
    
    1. 使用INCLUDE 
    
        EXEC SQL INCLUDE sqlda;
    
    2. 使用指针
    
        EXEC SQL INCLUDE sqlda;
        sqlda *bind_dp;
        sqlda *select_dp;
        bind_dp=sqlald(....);
        select_dp=sqlald(....);
    
    SQLDA的应用
    
        对于每一个动态的SQL都应该说明一个SQLDA.
    
    库函数sqlprc()分离精度和定标。
    
    
    用户出口(SQL*Forms)
    
    EXEC IAF GET
    EXEC IAF PUT
    
    EXEC IAF GET 将form中的值取出赋给宿主变量
    
    例 EXEC IAF GET brand_id INTO :brand; //将brand_id的值取出赋给宿主变量brand
    
    EXEC IAF PUT 将常量或宿主变量的值放入forms中
    
    例 EXEC IAF PUT brand VALUES(:brand_id);
    
    
    用户出口的引用
    
     方法:  定义触发器,在触发器中,用USER_EXIT(user_exit_string[,error_string])引用出口。
    
    
    
    错误处理
    
    whenever 子句
    
    EXEC SQL WHENEVER {SQLERROR|NOT FOUND|SQLWARNING}
               {CONTINUE|DO function call|DO break|GOTO table|STOP};
  • 相关阅读:
    TCP 传递信息
    如何在数据源是空的时候,gridview显示表头(万能)
    (orm1)O/R Mapping在实际中用于什么方面最有优势?[转]
    web service 数据传输有什么限制? 为什么?DataTable可以作为web service参数传递么?90
    C#对象的 Xml序列化与反序列化
    题目:当点击按钮时,如何实现两个td的值互换?【js】
    4.如何获取动态生成的SL控件的NAME值(二)
    gridview排序加箭头(二)
    我们没有在一起
    (orm 2) LINQ与ORM
  • 原文地址:https://www.cnblogs.com/tychyg/p/5068942.html
Copyright © 2020-2023  润新知