初学者Oracle数据库:Proc和Proc++的使用和示例

  一.什么是pro程序
   1.1通过在过程化编程语言中 嵌入sql语句开发出的应用程序
   叫做pro程序。
   1.2为什么要使用proc/c++
   想使用c或者c++ 这种高效的语言 成为访问oracle数据库的
   工具。
   
   sql语句是嵌入在c 或者c++ 语言上
   c 和 c++ 是宿主语言
 二.proc 程序 和c 相同点和不同点
   需要导入头文件 就导入头文件 
   需要定义函数 就定义函数
   需要定义变量 就定义变量
   
   不同点需要在操作数据库的操作前加 exec sql
   包含一个和数据库操作相关的数据结构
   exec sql include sqlca;
   连接数据库
   exec sql connect:usernameandpasswd;
   查询数据
   exec sql select  first_name  into  :变量
       from s_emp where id=1;
   关闭数据库连接
   exec sql commit work release;
   exec sql rollback work release;
 三.写一个c程序的步骤
    3.1  编写源代码
         vi  ***.c 
    3.2  编译 链接
         gcc  ***.c   -l库名
    3.3  执行
         ./a.out
 四.写一个proc程序的步骤
    4.1  编写源代码
         vi   ***.pc 
    4.2  预编译  把pc文件变成c文件
         proc   ***.pc 
    4.3  编译链接
         gcc    ***.c   -lclntsh
                        -lorasql10                  
    4.4  执行
         ./a.out
               
               
    ftp   192.168.0.26
    openlab
    open123
    mkdir   文件夹
    cd      文件夹
    put     文件名 (上传文件)       
    get     文件名 (下载文件)     
         
 五.宿主变量
    5.1  概念
    使用宿主语言定义的变量。
    即可以在宿主语言中使用,又可以在sql语句中使用。
    5.2  宿主变量的类型
    char   
    char      var[n]   定长字符串
    short   
    int 
    long 
    float
    double 
    varchar   var[n]   变长字符串
    
    5.3  定长字符串 和 变长字符串
       定长   char     var[n];
       变长   varchar  var[n];
       在select语句中 要和正常变量一样去使用
       在宿主语言中  要使用.arr 取得数据 
                     .len 存放的是数据的长度   
    5.4  使用proc的预编译选项 来处理字符串
       gcc    -c   -E   -S
       proc   char_map=charz  定长  空格补齐  \0结尾
                      =charf|varchar2 定长 空格补齐
                      =string  变长  \0结尾  
    5.5  宿主变量的使用注意事项
       5.5.1 宿主变量 强烈建议放入申明区  
       exec sql  begin declare section;
         
       exec sql  end   declare section;    
       5.5.2 proc 中可以直接使用ddl
             但ddl中不能使用宿主变量
       char  var_name[30]="s_emp";
       exec  sql   drop  table  var_name;      
       5.5.3 可以使用指针  但必须分配内存
             对字符串的动态内存分配支持的不好
             不建议使用
       5.5.4 宿主变量在sql语句中使用时 建议加上:
                   
       
 六. 指示变量
     6.1  作用
     当数据库中的字段值 赋值给宿主变量时 赋值的状态
     可以通过指示变量得到。
     ==0   代表赋值正常
     ==-1  数据库中的字段值是NULL值
     >0    代表截断赋值  尽量避免    
     6.2  语法
     必须是short类型的变量
     short  indname=0;
     short  indsal=0;
     exec sql select first_name,salary  into 
         :var_name:indname,:var_sal indicator :indsal  
         from s_emp where id=1;   
     6.3  例子
     把id=1 的 manager_id  赋值给一个宿主变量  赋值
     的状态通过指示变量 得到。
     
 七.数组变量 
    7.1 使用数组变量的注意事项
       只支持一维数组  字符除外   char data[50][30];
       不支持数组指针  
       最大元素个数 32767
       使用数组时 在select语句中 只能出现数组的名字
       不能出现数组的下标。
    7.2 举例
       把s_emp 表中所有的 first_name 和 manager_id 
       分别放入两个数组中  并且要指示manager_id 的
       赋值状态。  
 八.sqlca通信区
    exec sql  include sqlca;
    sqlca 实际上是一个结构体,在一个事务中 每执行一次
    sql语句,就会把这个结构体中字段更新一遍。所以我们
    要得到sql语句执行的信息 要立即获得 否则将下一条
    sql覆盖掉。
    sqlca.sqlerrd[2]  获得sql语句影响的行数
    sqlca.sqlcode     sql语句执行状态
        ==0    sql语句执行正常
        >0     出现异常
        <0     网络错误 或者数据库本身错误
    sqlca.sqlerrm.sqlerrmc   sql出错的原因
    
    转账操作?
    可以得到sql语句的状态
九. oraca 通信区(了解)
    是对sqlca的信息补充。
    根据设置的条件得到sql语句
    9.1  包含oraca
    exec sql  include  oraca;
    9.2  打开oraca
    exec oracle    option(oraca=yes);
    9.3  设置sql的保存标志
    oraca.orastxtf
    =0   默认的 不保存sql文本
    =1   sql出错时保存
    =2   sql 出现警告 或者出错时保存
    =3   无论什么情况都保存
    9.4  得到sql文本
    oraca.orastxt.orastxtc
十. proc 中如何嵌入sql语句
   10.1 如何嵌入select语句
       在select 语句前加exec sql
       结合into 把查询的内容放入宿主变量
   10.2 如何嵌入 dml(insert delete update)
                 ddl(create drop  alter)
                 tcl(commit  rollback savepoint) 
        在这些语句前加exec sql
        ddl 中不能使用宿主变量
        
   使用proc 连接数据库  在程序中建立一张表
   id     number   primary key
   name   varchar2(30)  unique
   并且判断建表是否成功
   然后使用 insert  向表中放入一条数据
   id 和name 的值来自于宿主变量
   然后判断是否插入成功 
   再使用 update语句 把 id=1 的 name 更新成
   'test'
   使用查询语句把 id=1 name 查询出来 放入宿主变量
   打印验证update的结果

一.proc 中如何嵌入plsql
   1.1 proc程序中需要出现的代码
   exec  sql  execute
       begin
           /* 这里相当于匿名块 */
       end;
   end-exec;     
   
   1.2 首先 写一个存储过程准备调用
       设计一个存储过程 传入两个整数参数 
       把两个参数的和 存入第二个参数中。
   create or  replace  procedure getsum(
   x  in number,y in out number)
   is
   begin
       y:=x+y;
   end;
   
   1.3 预编译时 
       sqlcheck=semantics
       userid=用户名/密码  是在预编译时连接数据库
              确定存储过程是否存在和合法。
       proc  ***.pc sqlcheck=semantics 
           userid=openlab/open123
       gcc  ***.c  -lclntsh     
   1.4 写一个函数 传入两个整数参数 返回两个参数的最大
       值。使用proc程序调用 验证函数的功能 
       要求函数的参数 必须采用宿主变量传入。
       create or replace function  getmax(
       x  in number,y in number)return number  
       is
       begin
           if x<y then
              return  y;
           end if;
              return  x;    
       end;
 二.数据库的连接
    2.1 本地数据库连接
    exec sql  connect:userpasswd;
    exec sql  connect:name  identified by  :password;         
    连接的数据库是  (数据库服务名)
    echo     $ORACLE_SID
    2.2 远程数据库连接
    $ORACLE_HOME/network/admin/tnsnames.ora 
    CAH_192.168.0.26 =
   (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = tarena)
    )
    2.3 使用远程数据库描述连接远程数据库
         
       exec sql connect:userpassword at:标签名 using 远程数据库描述;
       exec sql connect:userpasswd at:标签名;
       只要在以后的每个操作前加上
       exec sql at :标签名   即可
    2.4 使用数据库链的方式 连接远程数据库
       create   database link  my26link 
       connect  to  openlab  identified  by open123
       using '(DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.26)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = tarena)
    )';
       
     select  id,first_name from s_emp;
     select  id,first_name from s_emp@my26link;
     
     select  id,salary from 
         s_emp@my26link where id=15;
     update  s_emp@my26link  set salary=salary+100
         where  id=15;
     select  id,salary from 
         s_emp@my26link where id=15;        
     远程数据库数据操作的事务 完全交给本地操作来控制。
     
     a.根据语法建立数据库链接 
     b.在proc代码中使用数据库链接
       在表名后 跟上@链接名
 
 三.proc  中的错误处理
    sqlca.sqlcode  用来判断sql语句的执行状态
    sqlca.sqlerrm.sqlerrmc 当sql出错之后得到错误的
                           内容。
    是局部处理 还是全局处理   
    
    exec sql whenever  条件  动作;
    条件:sqlerror   notfound   sqlwarning 
    动作:do  错误处理函数();
         do  break;  用来终止循环
         continue;  忽略错误继续处理
         stop;
         goto  标签;         
   proc  对sql错误的处理 采用的是忽略 
    
 四.  数据的操作
    4.1 使用单个变量 一次操作单行单列
    exec sql  select first_name  into :var_name 
        from s_emp where id=1;   
    4.2 使用多个变量 一次操作单行多列
    exec sql  select id,first_name,salary  into
    :id,:name,:salary from s_emp where id=2;  
    4.3 使用结构体到达多个变量的效果
    
    4.4 多个数组操作 多行多列
    4.5 游标操作多行多列
五. proc 中的游标操作
    5.1 游标的使用步骤
       声明游标
       exec sql  declare 游标名 cursor for select语句;
       打开游标
       exec sql  open  游标名;
       提取数据
       exec sql  fetch 游标名 into 宿主变量;
       关闭游标
       exec sql close  游标名;
    5.2 举例
       select  id,first_name,salary from s_emp;   
    5.3 如何遍历游标中所有的数据
       exec sql  whenever notfound  do break;   
    5.4 滚动游标(了解)
       (可以不按照顺序提取游标中的数据)        
        scroll
        fetch  last    最后一条
               first   第一条
               prior   当前行的前一条
               next    当前行的下一条  
               current  当前
               relative  n  n是正数是向后
                            n是负数向前
               absolute  n  绝对的第几个 
 六 动态sql
    把字符串 对应的sql语句当真正的sql来执行
    6.1  不能是select
         不能有占位符 
         exec sql  execute immediate :sqlstr;
    6.2  可以有占位符
         不能是select
         exec sql  prepare s  from :sqlstr;
         exec sql  execute s  using  宿主变量。
    6.3  只能是select语句
         可以有占位符 
         "select  id,first_name,salary from s_emp where id>:b0"
          
          动态sql2  和 游标的结合
          
------------------------------------------------------          
 触发器         
     进行dml 操作时  系统可以做出相应的动作。
     create table  testemp9526  as select id, first_name,salary from s_emp;    
     create  or  replace  trigger  testemp9526_tri
     before   update   on testemp9526 
     declare
     begin
         dbms_output.put_line('update testemp9526');
     end;
     
     update   testemp9526 set salary=salary+100 where id=1;
     update   testemp9526 set salary=salary+100 where id<1;
     update   testemp9526 set salary=salary+100 where id>1;
     语句级触发器  无论sql语句影响多少行  触发器只触发 一次。
     行级触发器:sql 语句影响多少行 就触发多少次
     create  or  replace  trigger  testemp9526_tri
     before   update   on testemp9526 for each row
     declare
     begin
         dbms_output.put_line(:old.id||':'||:old.salary); 
         dbms_output.put_line('update testemp9526');
         dbms_output.put_line(:new.id||':'||:new.salary); 
     end;
        
     update   :old   :new 
     delete   :old
     insert          :new
     
     
     触发器中 不能出现事务控制语句
     事务谁发起 谁结束。
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值