`
lpm528
  • 浏览: 83463 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

oracle存储过程基础语句

 
阅读更多
可以用oracle已经存在的账号scott密码triger登陆进去用里面已存在的表来做试验。
create or replace procedure lpmtest2
as 
  para1 varchar2(10);
  cursor  youbiao is  select ename from test where sal>1300;
begin
  open youbiao;
  loop
    fetch youbiao into para1;
    exit when youbiao%notfound;
    dbms_output.put_line('++:'||para1);
  end loop;
  close youbiao;
end;--最后分号记得写,否则会报错。

 ======================================================================

create or replace procedure lpmtest2
as 
  cursor  youbiao is  select ename,sal,job from test where sal>1300;
  c_row youbiao%rowtype; --定义一个游标变量c_row ,该类型为游标youbiao中的一行数据类型
begin
  open youbiao;
  loop
    fetch youbiao into c_row;
    exit when youbiao%notfound;
    dbms_output.put_line('++:'||c_row.ename||':'||c_row.sal||':'||c_row.job);
  end loop;
  close youbiao;
end;

 =========================================================================

create or replace procedure lpmtest3
as
cursor c_dept is select * from dept order by deptno;
cursor c_emp(p_dept varchar2) is select ename,sal from emp where deptno=p_dept order by ename;
r_dept c_dept%rowtype;
v_ename emp.ename%type;
v_sal   emp.sal%type;
v_totalsal emp.sal%type; --用来存每个部门所有员工的总工资
begin
  open c_dept;
  loop
    fetch c_dept into r_dept;
    exit when c_dept%notfound;
    dbms_output.put_line(r_dept.deptno||':'||r_dept.dname||'+++++++++++');
    v_totalsal:=0;
    open c_emp(r_dept.deptno);
    loop
      fetch c_emp into v_ename,v_sal;
      exit when c_emp%notfound;
      dbms_output.put_line('v_ename:'||v_ename||';'||'v_sal:'||v_sal);
      v_totalsal:=v_totalsal+v_sal;
     end loop;
     close c_emp;
     dbms_output.put_line('deptsaltotal:'||v_totalsal);
   end loop;
   close c_dept;
end;

 打印出来效果:

10:ACCOUNTING+++++++++++
v_ename:CLARK;v_sal:2450
v_ename:KING;v_sal:5000
v_ename:MILLER;v_sal:1300
deptsaltotal:8750
20:RESEARCH+++++++++++
v_ename:ADAMS;v_sal:1100
v_ename:FORD;v_sal:3000
v_ename:JONES;v_sal:2975
v_ename:SCOTT;v_sal:3000
v_ename:SMITH;v_sal:800
deptsaltotal:10875
30:SALES+++++++++++
v_ename:ALLEN;v_sal:1600
v_ename:BLAKE;v_sal:2850
v_ename:JAMES;v_sal:950
v_ename:MARTIN;v_sal:1250
v_ename:TURNER;v_sal:1500
v_ename:WARD;v_sal:1250
deptsaltotal:9400
40:OPERATIONS+++++++++++
deptsaltotal:0

 ======================================================================

create or replace procedure lpmtest9(v_name varchar2)
is
v_num number:=1;
begin
  loop
     insert into lpm_user values(v_name,v_num);
     commit;
     exit when v_num=5;
     v_num:=v_num+1;
  end loop;
end;

 

=======================================================================

create or replace procedure lpmtest8(lpm_empno number)
is
lpm_job emp.job%type;
begin
  select job into lpm_job from emp where empno=lpm_empno; 
  if lpm_job='PRESIDENT' then
    begin
    update emp set sal=sal+500 where empno=lpm_empno;
    commit;
    end;
  elsif lpm_job='MANAGER' then  --是elsif不是elseif!要少个e
    begin
      update emp set sal=sal+300 where empno=lpm_empno;
      commit;
    end;
  else
    begin
    update emp set sal=sal+100 where empno=lpm_empno;
    commit;
    end;
  end if;
end;

 ========================================================

create or replace procedure lpmtest15(lpmEmpId emp.empno%type)
is 
addincrement emp.sal%type;
tempsal emp.sal%type;
begin
  select sal into tempsal from emp where empno=lpmEmpId;
  if tempsal>2000 then addincrement:=50;
  elsif tempsal>1500 then addincrement:=100;
  else addincrement:=150;
  end if;
  update emp set sal=sal+addincrement where empno=lpmEmpId;
  commit;
end;

 =================================================================

例:建立一个存储过程,将STUDENTS表中按学号指定的学生记录移至HISTORY表中。并在history表中增加移入日期 (删除STUDENTS表中的记录,同时录入到HISTORY表中)。
Create or replace procedure move( stuno varchar) is
Begin
/*将students中学号为stuno的记录插入到history表中*/
Insert into history(stu_id,name,sex,ldate) 
select stu_id,name,sex ,sysdate from students
where stu_id=stuno;
/*将students中学号为stuno的记录删除*/
delete from students
where stu_id=stuno;
end; 

 ========================================================================

现假设存在两张表,一张是学生成绩表(studnet),字段为:stdId,math,article,language,music,sport,total,average,step一张是学生课外成绩表(out_school),字段为:stdId,parctice,comment
通过存储过程自动计算出每位学生的总成绩和平均成绩,同时,如果学生在课外课程中获得的评价为A,就在总成绩上加20分。

create or replace procedure autocomputer(step in number) is
rsCursor SYS_REFCURSOR;
commentArray myPackage.myArray;
math number;
article number;
language number;
music number;
sport number;
total number;
average number;
stdId varchar(30);
record myPackage.stdInfo;
i number;
begi
i := 1;
get_comment(commentArray); --调用名为get_comment()的存储过程获取学生课外评分信息
OPEN rsCursor for select stdId,math,article,language,music,sport from student t where t.step = step;
LOOP 
fetch rsCursor into stdId,math,article,language,music,sport; 
exit when rsCursor%NOTFOUND;
total := math + article + language + music + sport;

for i in 1..commentArray.count   LOOP 
 record := commentArray(i);    
if stdId = record.stdId then  
 begin     
 if record.comment = 'A' then     
  begin         
 total := total + 20;   
    go to next; --使用go to跳出for循环       
  end;     
end if;  
end; 
end if; 
end LOOP;

average := total / 5;
update student t set t.total=total and t.average = average where t.stdId = stdId; 
end LOOP;

end;
end autocomputer;

--取得学生评论信息的存储过程
create or replace procedure get_comment(recommentArray out myPackage.myArray) is
rs         SYS_REFCURSOR; 
record    myPackage.stdInfo; 
stdId     varchar(30); 
comment  varchar(1); 
i          number;
begin
open rs for select stdId,comment from out_school
i := 1;
LOOP
 fetch rs into stdId,comment;
 exit when rs%NOTFOUND; 
record.stdId := stdId;
 record.comment := comment; 
recommentArray(i) := record; 
i:=i + 1; 
end LOOP;
end get_comment;

--定义数组类型myArray 
create or replace package myPackage is begin
type stdInfo is record(stdId varchar(30),comment varchar(1));
type myArray is table of stdInfo index by binary_integer;
end myPackage;

 ======================================================================

1. 存储过程格式

/* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */

CREATE OR REPLACE procedure proc_trade(

  v_tradeid in number,                        --交易id

  v_third_ip in varchar2,                     --第三方ip

  v_third_time in date ,                      --第三方完成时间

  v_thire_state in number ,                   --第三方状态

  o_result out number,                       --返回值

  o_detail out varchar2                     --详细描述

)

as

-- 定义变量

  v_error varchar2(500);

begin

    --对变量赋值

     o_result:=0;

     o_detail:='验证失败';

 

    --业务逻辑处理

    if v_tradeid >100 then

        insert into table_name(...) values(...);

        commit;

    elsif v_tradeid < 100 and v_tradeid>50 then

        insert into table_name(...) values(...);

        commit;

    else

            goto log;

    end if;

--跳转标志符,名称自己指定

<<log>>

        o_result:=1;

--捕获异常

exception

   when no_data_found

   then

      result := 2;

   when dup_val_on_index

   then

      result := 3;

   when others

   then

      result := -1;

end proc_trade;

 

            在上面这个存储过程中使用了输入参数,并返回输出参数,这里的参数类型是我们自己指定的。 这种写法可行,但是最好使用%type 来获取参数的类型(table_name.column_name%TYPE)。 这样就不会出现参数类型的错误。

 

如:

CREATE OR REPLACE PROCEDURE spdispsms (

   aempid      IN       otherinfo.empid%TYPE,

   amsg        IN       otherinfo.msg%TYPE,

   abillno     IN       otherinfo.billno%TYPE,

   ainfotype   IN       otherinfo.infotype%TYPE,

   aopid       IN       otherinfo.OPERATOR%TYPE,

   ainfoid     OUT      otherinfo.infoid%TYPE,

   RESULT      OUT      INTEGER

)

 

2. 存储过程中的循环

            存储过程写的是业务逻辑,循环是常用的处理方法之一。 

 

2.1  for ... in ... loop 循环

2.1.1:循环遍历游标

示例1:

CREATE OR REPLACE PROCEDURE proc_test

AS

   CURSOR c1

   IS

      SELECT   * FROM dat_trade;

BEGIN

   FOR x IN c1

   LOOP

      DBMS_OUTPUT.put_line (x.id);

   END LOOP;

END proc_test;

 

示例2:

CREATE OR REPLACE PROCEDURE proc_test

AS

BEGIN

   FOR x IN (SELECT   power_id FROM sys_power)

   LOOP

      DBMS_OUTPUT.put_line (x.power_id);

   END LOOP;

END proc_test;

 

2.1. 2:根据数值进行循环

示例1:

CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)

AS

BEGIN

     for x in 1..100 loop

         dbms_output.put_line(x);

     end loop;

END proc_test;        

 

示例2:在过程里指定输入参数v_num. 在调用过程时指定循环次数。

CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)

AS

BEGIN

   FOR x IN 1 .. v_num

   LOOP

      DBMS_OUTPUT.put_line (x);

   END LOOP;

END proc_test;        

 

 

2.2  loop 循环

   LOOP

      DELETE FROM orders

            WHERE senddate < TO_CHAR (ADD_MONTHS (SYSDATE, -3),

                                      'yyyy-mm-dd')

              AND ROWNUM < 1000;

 

      EXIT WHEN SQL%ROWCOUNT < 1;

      COMMIT;

   END LOOP;

 

这里的SQL%ROWCOUNT 是隐士游标。 除了这个,还有其他几个:%found,%notfound, %isopen。 

 

2.3  while 循环

CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)

AS

   i   NUMBER := 1;

BEGIN

   WHILE i < v_num

   LOOP

      BEGIN

         i := i + 1;

         DBMS_OUTPUT.put_line (i);

      END;

   END LOOP;

END proc_test;

 

3. 存储过程中的判断

            判断也是存储过程中最常用的方法之一。

 

3.1  if ... elsif ... else ... 判断

CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)

AS

BEGIN

   IF v_num < 10

   THEN

      DBMS_OUTPUT.put_line (v_num);

   ELSIF v_num > 10 AND v_num < 50

   THEN

      DBMS_OUTPUT.put_line (v_num - 10);

   ELSE

      DBMS_OUTPUT.put_line (v_num - 50);

   END IF;

END proc_test;

 

3.2  case ... when ... end case 判断

CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER)

AS

BEGIN

    case v_num

        when 1 then

             DBMS_OUTPUT.put_line (v_num);

        when 2 then

            DBMS_OUTPUT.put_line (v_num);

        when 3 then

            DBMS_OUTPUT.put_line (v_num);

        else null;

    end case;   

END proc_test;

 

4. 游标

            存储过程中使用游标也是很常见的。 这里的游标分两种:

 

4.1  Cursor型游标(不能用于参数传递)

            这种方法具体参考 2.1.1:循环遍历游标 中的示例。 

 

4.2  SYS_REFCURSOR型游标

            该游标是Oracle以预先定义的游标,可作出参数进行传递。 

            注意一点:SYS_REFCURSOR只能通过OPEN方法来打开和赋值

 

4.2.1  我们可以使用这种类似的游标来返回一个结果集:

 

CREATE OR REPLACE procedure  proc_test(

checknum in number,  --每次返回的数据量

ref_cursor out sys_refcursor  --返回的结果集,游标

)

as 

begin

    open ref_cursor for select * from (select * from dat_trade where state=41 order by id) where rownum<checknum;

end proc_test;

/

 

SYS_REFCURSOR中可使用三个状态属性:

(1).            %NOTFOUND(未找到记录信息) 

(2).            %FOUND(找到记录信息) 

(3).            %ROWCOUNT(然后当前游标所指向的行位置)

 


CREATE OR REPLACE PROCEDURE proc_test (

checknum     IN     NUMBER, --每次返回的数据量
ref_cursor      OUT sys_refcursor --返回的结果集,游标
)
AS
t_tmp   table_name%ROWTYPE;
BEGIN
   OPEN ref_cursor FOR
      SELECT   *

        FROM   (  SELECT   *

                    FROM   table_name

                   WHERE   state = 41
                ORDER BY   id)
       WHERE   ROWNUM < checknum;
--循环游标
   LOOP
      FETCH ref_cursor INTO   t_tmp;
      EXIT WHEN ref_cursor%NOTFOUND;
--    DBMS_OUTPUT.put_line (t_tmp.id);
      UPDATE   table_name

         SET   state = 53
       WHERE   id = t_tmp.id;
      COMMIT;
   END LOOP;

 

   CLOSE ref_cursor;
END proc_test;

 

分享到:
评论

相关推荐

    oracle存储过程学习经典入门

    Oracle 存储过程的基础知识包括了解 Oracle 存储过程的基本语法、数据类型、变量声明、控制语句、循环语句、异常处理等方面的知识。 Oracle 存储过程的基本语法 Oracle 存储过程的基本语法主要包括 CREATE ...

    oracle存储过程

    oracle 存储过程的基本语法 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程名字 ( 参数1 IN NUMBER, 参数2 IN NUMBER ) IS 变量1 INTEGER :=0; 变量2 DATE; BEGIN END 存储过程名字 2.SELECT INTO ...

    oracle存储过程解锁

    以下是对“oracle存储过程解锁”这一主题的深入解析。 ### 标题:“oracle存储过程解锁” #### 解析: 在Oracle数据库中,存储过程是一种预先编译并存储在数据库中的SQL代码块,用于执行复杂的业务逻辑或数据处理...

    oracle存储过程unwrap解密工具.zip

    Oracle存储过程是数据库管理员和开发人员用来封装SQL语句和PL/SQL代码的单元。它们可以执行复杂的业务逻辑,提高性能,并简化数据库操作。在某些情况下,存储过程可能被加密,这可能是出于安全考虑,防止未授权访问...

    oracle存储过程-帮助文档

    Oracle存储过程是数据库管理系统中的一种重要特性,它允许开发者编写一系列SQL语句和PL/SQL块,形成可重复使用的代码单元。这篇博客“oracle存储过程-帮助文档”可能提供了关于如何创建、调用和管理Oracle存储过程...

    帆软报表Oracle存储过程解决storeParameter1参数试用插件

    总结起来,"帆软报表Oracle存储过程解决storeParameter1参数试用插件"主要是针对在调用无参数Oracle存储过程时出现的异常问题提供的一种解决方案。通过安装并配置这个插件,用户可以顺利地在帆软报表中调用不包含...

    oracle 事务 回滚 存储过程

    ### Oracle存储过程 存储过程是在数据库中预编译的一组SQL语句,用于执行复杂的业务逻辑或数据操作。它们可以接受输入参数,执行一系列数据库操作,并返回结果。在Oracle中,存储过程使用PL/SQL编写,可以在数据库...

    ORACLE存储过程最全教程

    这篇教程将深入讲解Oracle存储过程的各个方面,帮助你从基础到高级全面掌握这一技能。 一、存储过程的基本概念 存储过程是Oracle数据库中的一组有序的PL/SQL语句,可以包含变量声明、条件判断、循环结构以及SQL操作...

    oracle 存储过程中某入参是逗号分隔,并且参数要使用在in过滤语句中

    oracle存储过程中入参是逗号分隔,并且参数要使用在in过滤语句中查询数据。处理的方法与实现

    oracle存储过程基础教程

    这个基础教程将带你深入理解Oracle存储过程的概念、创建、执行以及调用方法。 一、Oracle存储过程概述 Oracle存储过程是预编译的SQL和PL/SQL代码集合,它们在数据库中作为一个单元进行存储和管理。存储过程可以提高...

    oracle存储过程常用技巧

    Oracle存储过程常用技巧 Oracle存储过程是一种强大的数据库对象,它可以帮助开发者简化复杂的业务逻辑,并提高数据库的安全性和性能。在 Oracle 中,存储过程是一种特殊的 PL/SQL 程序,它可以接受输入参数,执行...

    oracle 存储过程批量提交

    ### Oracle存储过程批量提交知识点详解 在Oracle数据库中,存储过程是一种重要的数据库对象,它可以包含一系列SQL语句和控制流语句,用于实现复杂的业务逻辑处理。存储过程不仅可以提高应用程序性能,还可以确保...

    存储过程中怎么动态执行sql语句

    通过以上两个示例可以看出,在Oracle存储过程中实现动态SQL语句的关键在于利用`EXECUTE IMMEDIATE`动态执行SQL语句以及通过创建包的方式来实现更为复杂的动态数据处理逻辑。这两种方法不仅提高了代码的灵活性,还...

    hibernate query调用oracle存储过程

    以下是一个简单的示例,展示了如何调用一个不带参数的Oracle存储过程: ```java Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); session....

    pb中执行oracle存储过程脚本

    Oracle存储过程则是在Oracle数据库中预编译的一系列SQL和PL/SQL语句,可以视为数据库端的可执行代码。 在描述中提到的“使用批处理进行oracle存储过程脚本的创建和更新的处理”,这可能意味着开发者使用批处理命令...

    oracle存储过程学习经典

    #### Oracle存储过程基础知识与实践 Oracle存储过程是SQL与PL/SQL结合的强大功能,用于封装复杂的数据操作逻辑于数据库内部,从而实现高效的事务处理和数据管理。以下是对Oracle存储过程的一些关键知识点的深入解析...

    C#中调用oracle存储过程返回数据集

    在C#中调用Oracle存储过程来返回数据集是一个常见的任务,这涉及到ADO.NET库的使用,特别是OracleClient组件。Oracle存储过程是数据库中的预编译SQL代码块,可以接收输入参数,执行复杂的业务逻辑,并返回结果。在C#...

    ORACLE存储过程学习源码

    这个"ORACLE存储过程学习源码"集合包含了从基础到高级的30个示例,是学习和掌握Oracle存储过程的理想资源。下面,我们将深入探讨存储过程的基本概念、结构、类型,以及如何通过这些源码进行学习。 1. **存储过程的...

    Oracle存储过程开发的要点

    Oracle存储过程是数据库管理系统Oracle中的一种重要特性,用于封装一系列SQL和PL/SQL代码,以实现特定的功能。在Oracle中,存储过程可以提高应用程序的性能,因为它减少了与数据库的交互次数,并允许在数据库级别...

Global site tag (gtag.js) - Google Analytics