oracle9i存储过程、触发器、函数简单实例(基于PL/SQL7.1)

时间:2022-02-03 20:57:19

第一:已经存在表PUB_T_DIVISION_TEST,可以使用以下的语句创建
 create table PUB_T_DIVISION_TEST(
   DIVID       VARCHAR2(30) not null,
   DIVNAME     VARCHAR2(60) not null,
   SUPERID     VARCHAR2(30) not null,
   DIVLVLID    VARCHAR2(30) not null,
   ENDFLAG     VARCHAR2(30) not null,
   ADDR        VARCHAR2(30),
   POSTALCODE  VARCHAR2(30),
   TEL         VARCHAR2(30),
   DIVTYPE     VARCHAR2(30),
   ISSELF      VARCHAR2(30),
   BREVIARY    VARCHAR2(30),
   DEFPASSWORD VARCHAR2(30),
   SHOWID      VARCHAR2(30),
   DISTRICTID  VARCHAR2(30),
   ISXZQH      VARCHAR2(30),
   ADMINMANID  VARCHAR2(30)
 )
 tablespace EFMWEB
   pctfree 10
   initrans 1
   maxtrans 255
   storage
   (
     initial 64K
     minextents 1
     maxextents unlimited
   );
插入几条数据:
insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH, ADMINMANID)
values ('001', '门头沟*, '#', '0001', '0', '', '', '', '01', '0', '', '', '001', '', '', '');
insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH, ADMINMANID)
values ('087', '街道预算', '001', '00010002', '0', '', '', '', '01', '0', '', '', '087', '', '0', ' ');
insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH, ADMINMANID)
values ('087001', '街道预算', '087', '000100020001', '1', '', '', '', '01', '0', '', '', '087001', '', '0', ' ');
insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH, ADMINMANID)
values ('088', '乡镇预算', '001', '00010003', '0', '', '', '', '04', '0', '', '', '088', '', '', '');
insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH, ADMINMANID)
values ('088001', '乡镇预算', '088', '000100030001', '1', '', '', '', '01', '0', '', '', '088001', '', '0', ' ');

第二:使用PL/SQL连接上oracle,连接过程如下    
    1) 安装过程略,
    2)配置PL/SQL:
     打开 Tools->Preferences
     假设你的oracal安装路径是:E:/java/ora90
     那末:
     Oracle Home:E:/java/ora90
     Oci  Libray:E:/java/ora90/bin/oci.dll  //这里主要是指出oci.dll的存放位置
     点击“apply”"OK"。
     以上的设置是建立在你已经安装了oracle的客户端程序,如果不想安装oracle的客户端也想使用PL/SQL
     在本地连接  远程的oracle服务器,你需要一个绿色版的客户端,这个客户端很小,大概在10几M,解压缩到一定路径,根据实际路径设定
     Oracle Home和Oci  Libray的值,并仿照这个路径E:/java/ora90/network/admin/tnsnames.ora建立tnsnames.ora文件
    
    3)更改配置文件
      使用文本编辑器打开E:/java/ora90/network/admin/tnsnames.ora 文件,
      DFCS =
       (DESCRIPTION =
            (ADDRESS_LIST =
               (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.111)(PORT = 6666))
           )
            (CONNECT_DATA =
                (SERVICE_NAME = dddd)
           )
      )
      Host是你需要连接oracle服务器的地址,不一定是本地
      Port是oracle服务器的端口,根据实际情况进行设定
      Service_Name是服务器上的服务名称,根据实际情况设定
    4)重新启动pl/sql,填写用户名和密码 还有SERVICE_NAME 就可以登陆了
      不能登陆pl/sql有以下几种可能:
      a)密码帐号错误
      b)已经安装过oracle,卸载不完整,遗留了环境变量,在使用绿色版客户端时总是提示找不到服务ID,
         可以手动更新原有的oracle环境变量恢复成安装以前,就可以了
第三:函数
   可以看我转载的‘oracle函数大全’,或者你去搜

第四:触发器
  1)File>new->Program WIndow->Trigger
    Name:test_division_trigger  //触发器的名称,触发器不能被直接调用,只能由数据库的操作间接调用
    Fires: before  //需要被触发的操作是在事件执行前(before)或者后(after)才被执行
    Event: insert   //触发时件是什么类型的,insert:当有插入操作时触发才被执行,update,delete   
    Table or View: pub_t_division_test//操作的表明称
    StatementLevel: //不知道
  2)
  create or replace trigger test_division_trigger -- 创建触发器,如果已经存在同名的触发器,这个
                                                                                    --将覆盖原有的
    after update or insert                                          --确定事件在有更新或者插入操作时才被触发
    of superid                                                             --触动触发条件的参数名称
    on pub_t_division_test                                       --表名,还没有研究多个表的情况
    referencing old as old_value                            --定义新值 就值
                        new as new_value
    for each row      
    when (new_value.superid<>'001' )              --触发条件:在更新或者插入的心智当中的superid字段的值不是
                                                                                                         --001,就执行事件
    begin
      :new_value.addr :='北京市海淀区上地';   --在满足上述条件的情况下 更新或插入的这一条记录中addr
                                                                                --字段的值将被置成:北京市海淀区上地
    end test_division_trigger;                            --结束
  3)测试
   insert into PUB_T_DIVISION_TEST (DIVID, DIVNAME, SUPERID, DIVLVLID, ENDFLAG, ADDR, 
     POSTALCODE, TEL, DIVTYPE, ISSELF, BREVIARY, DEFPASSWORD, SHOWID, DISTRICTID, ISXZQH,  
      ADMINMANID)
   values ('088009', '乡镇预算9', '088', '000100030001', '1', '', '', '', '01', '0', '', '', '088001', '', '0', ' ');
   这条记录的superid是088 不等于001 所以这个条记录的addr的值将在插入前被置成:
   北京市海淀区上地  而不是‘’
   select *  from pub_t_division_test  where divid='088009'
   addr的值被置成:北京市海淀区上地 而我们插入时是“”。
 

第五:存储过程
    1)File>new->Program WIndow->Package
      Name:test_package
      Purpose: //不知道
    2)create or replace package test_package as
        type test_cursor  is  ref cursor; //建立一个cursor类型的变量test_cursor,为了返回一个结果集
      end test_package;
    3)File>new->Program WIndow->Procedure
     Name: add_division_test   // 存贮过程的名称,以后将以这个名称调用这个存贮过程 
     Parameters: temp_superid  in varchar2,  //需要输入的参数,字符型   
     temp_cursor out test_package.test_cursor  //返回参数,名称是在包中定义的,
                                                                                   //这个类型的参数是为了返回结果集
    4)
    create or replace procedure add_division_test( --创建存贮过程
      temp_superid  in varchar2,                   --输入参数类型,根据情况而定,不一定每次都要有输入输出参数
      temp_cursor out test_package.test_cursor     --返回参数类型,如果不是一个结果集
                                                                                   可以使用varchar,number等基本类型
     )
    as                                             --过程体
    begin                                          --过程开始
        open temp_cursor for select *  from  
   PUB_T_DIVISION_TEST  f 
  where f.superid=temp_superid  ;           --将一个以select的结果集保存到我们事先定义好的cursor类型变量中去
    end add_division_test;
    5)使用
    public void doTest_Procedure() {
  Connection con = this.getConn();
  CallableStatement csmt = null;
  ResultSet rs = null;
  System.out.println("------con:" + con);
  String sql = "{call   add_division_test(?,?)} ";//执行存贮过程的sql,参数个数要匹配
  try {
   csmt = con.prepareCall(sql);//必须使用CallableStatement
   csmt.setString(1, "001"); //设置第一个参数的值
   csmt.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
         //设置第二个参数的值,这个参数时输出参数,类型是cursor
   csmt.execute(); //执行存储过程
   //取出第二个参数的值,这个参数的值已经不是执行之前,现在其内容是存贮过程执行的结果,
   rs=(ResultSet)csmt.getObject(2);  
    //并将其强制转换成为ResultSet,便于后续的操作
   System.out.println("-------rs:"+rs);
   int i=0;
   while (rs.next()){//显示结果集中的内容
                  i++;
                 System.out.print("---["+i+"]---divid:"+rs.getString(1));
                 System.out.print("---divname:"+rs.getString(2));
                 System.out.print("---superid:"+rs.getString(3));    
                System.out.println();
   }
   
  } catch (SQLException e) {
   e.printStackTrace();
  } finally {
   try {
    if (rs != null) {
     rs.close();
    }
    if (csmt != null) {
     csmt.close();
    }
    if (con != null) {
     con.close();
    }
   } catch (SQLException e) {
    e.printStackTrace();
   }

  }
 }
上面的例子有时候会出现 :类型长度大于最大长度 或者 非法协议 等错误提示 ,
那是你的jdbc驱动版本的问题,到oracle网站上下载新的jdbc驱动安装就会好了
以上的一些东西 其实很简单 没有什么技术含量  希望通过它能让初学者入门
至于高手就不要看了