Oracle简单存储过程示例(持续追加)

最后更新日:2014年12月17日
一些基本操作:
1、修改sys密码
cmd->sqlplus / as sysdba->alter user sys identified by 新密码
2、新建用户
cmd->sqlplus / as sysdba->create user 用户名 identified by 密码->
grant connect,resource to 用户名->conn 用户名/密码
3、系统管理员登录
sqlplus / as sysdba
一些注意点:
1、下面两句等价
--(+)表示该表为从表连接至主表,即可以理解为不带(+)的为基准表
select count(*) from aa09,aa10 where aa09.aaa100 = aa10.aaa100(+)
--left join表示以左表为基准,right join表示以右表为基准
select count(*) from aa09 left join aa10 on aa09.aaa100 = aa10.aaa100
2、Oracle自定义错误从-20000开始
3、备份表:create table A1 as select * from personinfo 
不要数据只要表结构可以加上 where 1=2
插入一条数据可以用insert into table select * from othertable
4、取模mod(12,5)
%:表示零个或者多个任意字符
_:代表一个任意字符
<any/all(子查询)
例:select id from personinfo where id < any (select id from personinfo where id = 25)
分页:
select * from
(select rownum r,id,personname from personinfo where rownum < 4)
where r > 1
得到日期的指定部分:select extract(year from sysdate) from dual
INTERSECT(交集),返回两个查询共有的记录
UNION ALL(并集),返回各个查询的所有记录,包括重复记录
UNION(并集),返回各个查询的所有记录,不包括重复记录
MINUS(补集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录
PL/SQL块:
declare
  --xxx
begin
  --xxx
end;
LOOP循环中可以使用IF结构嵌套EXIT关键字退出循环

存储过程的基本语法:
CREATE [OR REPLACE] PROCEDURE 存储过程名[(參数[IN|OUT|IN OUT] 数据类型...)] 
{AS|IS} 
[说明部分] 
BEGIN 
可运行部分 
[EXCEPTION 
错误处理部分] 
END [过程名]; 

假设没有指明參数的形式,则默认是IN

DROP PROCEDURE 存储过程名;删除存储过程


CREATE [OR REPLACE] FUNCTION 函数名[(參数[IN] 数据类型...)] 
RETURN 数据类型 
{AS|IS} 
[说明部分] 
BEGIN 
可运行部分 
RETURN (表达式) 
[EXCEPTION 
错误处理部分] 
END [函数名];

DROP FUNCTION 函数名;


var_name emp.name%TYPE; 
--通过使用%TYPE,var_name变量将同emp表的name列的类型绑定
var_roomRecord rooms%ROWTYPE; 
--将定义一个记录var_roomRecord ,该记录中的字段将与rooms表中的列相对应
--举个综合例子:
rlc41   lc41%rowtype;
--将定义一个记录rlc41,该记录中的字段将与lc41表中的字段相对应
pro_xxx_check(a,b,rlc41,c,d);
--在函数中调用一个存储过程,其它的不用关心,总之在该存储过程中rlc41是一个in out,即你可以认为我rlc41传进pro_xxx_check存储过程后,会出来一条新的rlc41记录
SELECT SEQ_CLZ138.NEXTVAL INTO rlc41.Clz138 FROM DUAL;
--得到一个自增序列
insert into lc41 values rlc41;
--将一条新的rlc41记录插入进lc41表中去

注意:要得到自增序列,需要先创建一个自增序列,简单示例如下:
CREATE SEQUENCE SEQ_CLZ138 INCREMENT BY 1 START WITH 1;


触发器基本知识:
CREATE OR REPLACE TRIGGER trigger_test
AFTER INSERT or update
/**of 字段*/ ON Test_Peopleinfo
FOR EACH ROW
  begin
    --if inserting then 
    --  insert into test_province values(1,'xx省');
    --else 
      insert into test_province values(1,'xx省');
    --end if;
  end;


示例一:
CREATE OR REPLACE PROCEDURE PRO_01
IS
V NUMBER(10);
BEGIN
  SELECT COUNT(*) INTO V FROM oracletest.FIRSTTABLE;
  DBMS_OUTPUT.PUT_LINE('查询总数为:'||V);  
END;

调用:
call PRO_01();

示例二:
CREATE OR REPLACE PROCEDURE PRO_02(x IN VARCHAR2,y OUT VARCHAR2)

IS

v_1 VARCHAR2(10);

--PL/SQL体开始

BEGIN

SELECT "NAME" INTO v_1 FROM oracletest.FIRSTTABLE WHERE "ID" = 1;
IF 1<5 THEN 
SELECT "NAME" INTO v_1 FROM oracletest.FIRSTTABLE WHERE "ID" = 2;
ELSIF 1<3 THEN
SELECT "NAME" INTO v_1 FROM oracletest.FIRSTTABLE WHERE "ID" = 3;
ELSIF 1<1 THEN
SELECT "NAME" INTO v_1 FROM oracletest.FIRSTTABLE WHERE "ID" = 4;
ELSE
SELECT "NAME" INTO v_1 FROM oracletest.FIRSTTABLE WHERE "ID" = 5;
END IF;

--NULL;

END;

调用:
DECLARE a VARCHAR2(10);
BEGIN
PRO_02('x',a);
DBMS_OUTPUT.PUT_LINE('a为:'||a);
END;


示例三:
CREATE OR REPLACE PROCEDURE PRO_03(x IN NUMBER DEFAULT 12)
IS
v NUMBER(10);
BEGIN
  --x不能被赋值,如x:=10是错误的
  v:=x*2;
  DBMS_OUTPUT.PUT_LINE('v为:'||v);  
END;

调用:
call PRO_03(15);


示例四:
CREATE OR REPLACE PROCEDURE PRO_04(x OUT NUMBER)
IS
BEGIN
  x:=30;
  DBMS_OUTPUT.PUT_LINE('x为:'||x);  
END;

调用:
DECLARE a NUMBER(10);
BEGIN
PRO_04(a);
DBMS_OUTPUT.PUT_LINE('a为:'||a);
END;


示例五:
CREATE OR REPLACE PROCEDURE PRO_05(x OUT INTEGER)
IS
i INTEGER;
j INTEGER :=100;
BEGIN
 FOR i in 1..9 LOOP
   j:=j+i;
 END LOOP;
   x:=j; 
END;

调用:
DECLARE x INTEGER;
BEGIN
  PRO_05(x);
  DBMS_OUTPUT.PUT_LINE(' x为:'||x);
END;


示例六:
/*
CREATE OR REPLACE PROCEDURE PRO_06(x OUT INTEGER)
IS
k INTEGER :=1;
CURSOR cur IS SELECT count(*) total FROM oracletest.FIRSTTABLE;
BEGIN
   FOR i in cur LOOP
     k:=k+i.total;  
   END LOOP;
   x:=k;
   DBMS_OUTPUT.PUT_LINE('x的值为:'||x);
END;
*/
CREATE OR REPLACE PROCEDURE PRO_06(x OUT INTEGER)
IS
k INTEGER :=1;
CURSOR cur IS SELECT ID,NAME FROM oracletest.FIRSTTABLE;
BEGIN
   FOR i in cur LOOP
     DBMS_OUTPUT.PUT_LINE('NAME的值为:'||i.NAME);  
   END LOOP;
END;

调用:
DECLARE x INTEGER;
BEGIN
  PRO_06(x);
  DBMS_OUTPUT.PUT_LINE(' x为:'||x);
END;



示例七:
CREATE OR REPLACE FUNCTION FUN_01(x IN varchar2) 
RETURN varchar2 
IS
C varchar2(10);
BEGIN 
C:=x;
IF C='a' THEN
  DBMS_OUTPUT.PUT_LINE('C的只值为:'||C);
  C:=C||':aaaaa'; -- ||表示字符串拼接
ELSIF C='b' THEN
  DBMS_OUTPUT.PUT_LINE('C的只值为:'||C);
  C:=C||':bbbbb';-- ||表示字符串拼接
ELSE
  DBMS_OUTPUT.PUT_LINE('C的只值为:'||C);
  C:=C||':其他';-- ||表示字符串拼接
END IF;
RETURN (C);  
END;

调用:
select FUN_01('c') from dual;


示例八:
CREATE OR REPLACE FUNCTION FUN_02(x IN varchar2,y OUT NUMBER) 
RETURN NUMBER 
IS
v NUMBER(10);
BEGIN 

IF x='a' THEN
  y:=1;
  v:=y+10;
  DBMS_OUTPUT.PUT_LINE('v的只值为:'||v);
ELSIF x='b' THEN
  y:=2;
  v:=y+20;
  DBMS_OUTPUT.PUT_LINE('v的只值为:'||v);
ELSE
  y:=3;
  v:=y+30;
  DBMS_OUTPUT.PUT_LINE('v的只值为:'||v);
END IF;
RETURN (v);  
END;

调用:
DECLARE 
  ret NUMBER(10);
  n NUMBER(10);
BEGIN
  ret:=FUN_02('a',n);
  DBMS_OUTPUT.PUT_LINE('out的值为:'||n);
  DBMS_OUTPUT.PUT_LINE('返回的值为:'||ret);
END;


示例九:
CREATE OR REPLACE FUNCTION FUN_03(x IN NUMBER)
RETURN NUMBER
IS
v1 NUMBER(10):=1;
v2 NUMBER;
BEGIN
  
  v2:=x;

  WHILE v2>1 LOOP
  v1:=v1+v2;
  v2:=v2-1;
  
  END LOOP;

  RETURN (v1);

END;

调用:
--结果为6
select  FUN_03(3) from dual;


使用中的一些注意点:
1、动态拼接语句执行时,不应该写成:
V:='SELECT PERSONNAME,PERSONCARD,FAVOURATEFOOD'||
   ' INTO V1,V2,V3'||
   ' FROM TEST_PEOPLEINFO'||
   ' WHERE 1=1 '||V;
   EXECUTE IMMEDIATE V; 

而应该写成:
V:='SELECT PERSONNAME,PERSONCARD,FAVOURATEFOOD'||
   ' FROM TEST_PEOPLEINFO'||
   ' WHERE 1=1 '||V;
   EXECUTE IMMEDIATE V INTO V1,V2,V3; 


举个综合例子:
建表语句:
-- ----------------------------
-- Table structure for TEST_STUDENTINFO
-- ----------------------------
DROP TABLE  "TEST_STUDENTINFO";
CREATE TABLE  "TEST_STUDENTINFO" (
"ID" NUMBER NOT NULL ,
"STUDENTNUM" VARCHAR2(10 BYTE) NOT NULL ,
"NAME" VARCHAR2(10 BYTE) NOT NULL ,
"AGE" NUMBER(3) NOT NULL ,
"HOBBY" VARCHAR2(200 BYTE) NULL 
)
LOGGING
NOCOMPRESS
NOCACHE

;
COMMENT ON COLUMN  "TEST_STUDENTINFO"."ID" IS '学生ID';
COMMENT ON COLUMN  "TEST_STUDENTINFO"."STUDENTNUM" IS '学号';
COMMENT ON COLUMN  "TEST_STUDENTINFO"."NAME" IS '姓名';
COMMENT ON COLUMN  "TEST_STUDENTINFO"."AGE" IS '年龄';
COMMENT ON COLUMN  "TEST_STUDENTINFO"."HOBBY" IS '年龄';

-- ----------------------------
-- Records of TEST_STUDENTINFO
-- ----------------------------
INSERT INTO  "TEST_STUDENTINFO" VALUES ('1', '10001', '小明', '20', null);

-- ----------------------------
-- Indexes structure for table TEST_STUDENTINFO
-- ----------------------------

-- ----------------------------
-- Checks structure for table TEST_STUDENTINFO
-- ----------------------------
ALTER TABLE  "TEST_STUDENTINFO" ADD CHECK ("ID" IS NOT NULL);
ALTER TABLE  "TEST_STUDENTINFO" ADD CHECK ("STUDENTNUM" IS NOT NULL);
ALTER TABLE  "TEST_STUDENTINFO" ADD CHECK ("NAME" IS NOT NULL);
ALTER TABLE  "TEST_STUDENTINFO" ADD CHECK ("AGE" IS NOT NULL);

-- ----------------------------
-- Primary Key structure for table TEST_STUDENTINFO
-- ----------------------------
ALTER TABLE  "TEST_STUDENTINFO" ADD PRIMARY KEY ("ID");


-- 如果这句未执行成功,请单独执行
create sequence seq_test_studentinfo increment by 1 start with 1;

存储过程语句:
CREATE OR REPLACE PACKAGE ORACLE_TEST IS

  SUCCESS     CONSTANT INTEGER := 0;    --定义成功常量0
  FAIL        CONSTANT INTEGER := 1;    --定义失败常量0
  FLAG_YES    CONSTANT BOOLEAN := TRUE; --定义YES常量true
  FLAG_NO     CONSTANT BOOLEAN := FALSE;--定义NO常量false
  
  TYPE str_array IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;--定义String数组
  
  TYPE value1 IS REF CURSOR;--定义游标value1
  TYPE value2 IS REF CURSOR;--定义游标value2
  TYPE value3 IS REF CURSOR;--定义游标value3

  FUNCTION OT_1(studentnum   in varchar2,--学号
                name         in varchar2,--姓名
                errormessgae out varchar2--错误信息
               ) return integer;         --返回状态
               
  FUNCTION OT_2(studentnum in varchar2,  --学号
                name       in varchar2   --姓名                
                ) return boolean;
                
  FUNCTION OT_3(status in  integer,--状态(0,1,其它)
                info   out varchar2--消息体
                ) return integer;--返回状态

END ORACLE_TEST;

CREATE OR REPLACE PACKAGE BODY ORACLE_TEST IS

 /**
  *方法说明
  *FUNCTION OT_1
  */
  FUNCTION OT_1(studentnum   in varchar2,                  --学号
                name         in varchar2,                  --姓名
                errormessgae out varchar2                  --错误信息
               ) return integer is                         --返回状态
               
    studentinfo TEST_STUDENTINFO%ROWTYPE;
    flag_status boolean;
    
  BEGIN
  
    flag_status := OT_2(studentnum,name);
    
    if flag_status = true then  
      
      select ts.studentnum,ts.name,ts.age,ts.hobby
      into studentinfo.studentnum,studentinfo.name,
           studentinfo.age,studentinfo.hobby
      from TEST_STUDENTINFO ts
      where ts.studentnum = studentnum
      and ts.name = name
      and rownum=1;--表示结果只取一条
      
      --create sequence seq_test_studentinfo increment by 1 start with 1;
      select seq_test_studentinfo.nextval into studentinfo.id from dual;
      
      insert into TEST_STUDENTINFO values studentinfo;
      
      return ORACLE_TEST.SUCCESS;
      
    else RETURN ORACLE_TEST.FAIL;
    
    end if;
    
    EXCEPTION 
      WHEN OTHERS THEN
         errormessgae := '系统异常';
         return ORACLE_TEST.FAIL;
    
  END;
  
 /**
  *方法说明
  *FUNCTION OT_2
  */
  FUNCTION OT_2(studentnum in varchar2,                   --学号
                name       in varchar2                    --姓名                
                ) return boolean is
    select_value TEST_STUDENTINFO.Id%type; --与TEST_STUDENTINFO表的id字段的类型相同
  BEGIN 
    
    select count(*) into select_value
    from TEST_STUDENTINFO ts
    where ts.studentnum = studentnum
    and ts.name = name;
    
    if select_value = 1 then RETURN ORACLE_TEST.FLAG_YES;
    else return ORACLE_TEST.FLAG_NO;
    end if;
    
    EXCEPTION 
      WHEN OTHERS THEN
        return ORACLE_TEST.FLAG_NO;  
     
  END;
  
 /**
  *方法说明
  *FUNCTION OT_3
  */
  FUNCTION OT_3(status in  integer, --状态(0,1,其它)
                info   out varchar2 --消息体
               ) return integer is  --返回状态
               
    v_array ORACLE_TEST.str_array;--定义一个String数组
    v_str varchar2(100) :='';--定义一个100长度的空数组
    v_cur ORACLE_TEST.value1;--定义一个弱类型游标
    CURSOR cur IS SELECT * FROM TEST_STUDENTINFO;--定义游标
    v varchar2(100);--定义一个动态sql语句拼接变量         
  BEGIN
    /**第一个判断开始*/
    if status=0 then 
      v_array(1) := 'abc';
      v_array(2) := 'def';
      v_array(3) := 'ghi';
      
      for i in 1..v_array.count loop
        v_str:=v_str || v_array(i);
      end loop;
      info:=v_str;
      
    elsif status=1 then 
      for v_cur in (select * from TEST_STUDENTINFO) loop
        v_str := v_str || v_cur.id || ',';
      end loop;
      v_str := substr(v_str,0,length(v_str)-1);
      info:=v_str;
      
    else info:='a';
      
    end if;
    /**第一个判断结束*/
    
    /**第二个判断开始*/
    if info is null then
      --插入初始值
      V:='INSERT INTO TEST_STUDENTINFO(ID,STUDENTNUM,NAME,AGE) '||
         ' VALUES('||'1,10001,''小明'',20'||')';
      EXECUTE IMMEDIATE V;--INTO V1,V2,V3;
      info:='b'; 
    else 
       FOR i in cur LOOP
           info:=i.id;
       END LOOP;
    end if;
    /**第二个判断结束*/
    
    return ORACLE_TEST.SUCCESS;
    
    EXCEPTION 
      WHEN OTHERS THEN
        return ORACLE_TEST.FAIL;
  
  END;

END ORACLE_TEST;


另:附件为一些常用的语句和函数

猜你喜欢

转载自quarterlifeforjava.iteye.com/blog/2124048