ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Oracle函数与存储过程

2022-06-10 18:33:23  阅读:130  来源: 互联网

标签:存储 end 函数 sal number emp Oracle out


一. PL/SQL块

  1. 命名的PL/SQL块:将一个完整业务逻辑的PL/SQL块起一个名字,然后进行独立的编译之后保存到数据库中,然后在后续使用时直接可以通过名称调用

  2. 匿名的PL/SQL块:重用性不高,并且执行效率也不高

  优点:代码重用性和效率比较高

  常见的命名的PL/SQL块:函数,存储过程,触发器,程序包等等

二. 函数

  自定义函数:

    语法:create [or replace] function 函数名[(参数列表)]

       return 数据类型

       is

        [变量声明]

       begin

        需要执行的语句;

        return 返回的值;

       end [函数名];

    使用场景:如果业务逻辑最终需要返回一个结果则可以使用函数。

    

    例子:

      create or replace function avg_sal return number

      is

       emp_avg_sal number;

      begin

       select avg(sal) into emp_avg_sal from emp;

       return emp_avg_sal;

      end avg_sal;

 

    调用方式:

      可以在select语句中调用,也可以在PL/SQL块中使用

    删除函数:

      drop function 函数名;

三. 存储过程

  存储过程:procedure

  (1)创建存储过程

    语法:create [or replace] procedure 存储过程名[(参数名 数据类型,参数名 数据类型,...)]

       is/as

        [变量的定义]

       begin

        需要执行的代码

       [exception

        异常处理]

       end;

    例子:

      create or replace procedure pro_insert_dept

      is

      begin

       insert into dept values(21,'销售部','深圳');

      end;

 

  (2)存储过程的调用

    在PL/SQL块调用

      语法:

       begin

        存储过程名;

       end;

      例子:(接上面)

       begin 

        pro_insert_dept;

       end;

    在sqlplus中调用

     execute/exec 存储过程名[(参数值,参数值,...)];

 

  (3)存储过程的参数

    形参:在函数或者是存储过程创建的时候规定的参数,没有具体的值

    实参:在函数或这是存储过程调用时传入的值或带有值的变量

    参数传递方式:

      1. 按照位置传参

       实参的顺序和形参的顺序要一一对应

      2. 按照形参传参

       语法:形参名 => 实参值

       例子:name => '张三'

      3. 混合传参

       既有按位置传参又有名称传参,但是如果第一个参数就是按照名称传参,后续一般不建议使用位置传参

 

  (4)存储过程的参数模式

    1. in模式:参数的值只能从存储过程外部传入,并且在存储过程内部不能对数据进行修改

     语法: 参数名 [in] 数据类型

     注意: 在存储过程创建时定义的参数模式默认为 in 模式 

     in模式参数的默认值设置:

      语法:参数名 in 数据类型 default 默认值

      如果给输入参数设置了默认值,则在调用的时候可以不用输入参数,但是要注意参数顺序

    2. out模式:输出参数,相当于函数中的return,out参数的值只能在存储过程内部被赋值,不能从外部传入

     语法: 参数名 out 数据类型

     例子:

      create or rplace procedure pro_select_emp (e_no number,e_name out varchar2,e_job out varchar2)

      is

      begin

       select ename,job into e_name,e_job from emp where empno = e_no;

      end;

     调用:

      declare

       e_name emp.ename%type;

       e_job emp.job%type;

      begin

       pro_select_emp(7369,e_name,e_job);

       dbms_output.put_line('姓名:'||e_name||' 职位'||e_job);

      end;

    3. in out 模式: 输入输出参数,参数的值可以从外部传入到存储过程内部,并且在内部进行重新赋值后返回

     语法:参数名 in out 数据类型

 

  (5)删除存储过程

    drop procedure 存储过程名

 

  (6)存储过程和函数的区别

    1. 关键字不同

    2. 函数必须使用 return 来返回数据,但是存储过程要使用 out 参数进行返回数据

    3. 函数可以用 select 语句进行调用,但是存储过程不能使用 select 语句进行调用

    4. 函数只能返回一个值,但是存储过程可以返回多个值

    5. 函数只有一种模式的参数,但是存储过程有3种模式的参数

四. 序列:sequence

  在 Oracle 数据库中,序列是可以用来生成一系列唯一的数字的一种数据库对象

  1. 序列的创建:

   create sequence 序列名

   [start with n    --序列产生的起始位置,默认为1

    increment by n   --序列增长的步长,默认为1

    minvalue n    --最小值,默认为1

    maxvalue n      --最大值,默认为99999999999999999999

    cache n|nocache   --缓存设置,默认为20

   ]

  2. 序列的使用

   nextval:生成下一条数字

   currval:获取当前的数字

   注意:在创建好一个序列之后,在使用currval之前必须先执行一次nextval来生成数字

   语法:select 序列名.nextval/currval from dual;

   使用:create table  user_t(

        u_id number,

        u_name varchar2(20)

      )

      insert into uesr_t values (序列名.nextval,'小明');

五. 程序包

  将数据库中的对象封装到一起,方便后期的管理和维护,并且可以提高程序的效率

  程序包的组成

   1.程序包规范:package

    规范中主要保存一些声明操作,比如:游标、类型、变量、存储过程的声明,函数的声明等

    语法:create [or replace] package 包名

       is

       [游标声明]

       [变量声明]

       [类型声明]

       [存储过程声明]

       [函数声明]

       end [包名];

    例子:

     create or replace package pack_age

     is

      procedure pro_emp(e_no number,e_name out varchar2,e_sal out number);

      function fun_sal(e_deptno number) return number;

     end pack_age;

   2.程序包主体:package body

    主要就是对规范中的声明的子程序进行一个具体的实现

    语法:create or replace package body 包名

       is

       [存储过程的实现]

       [函数的实现]

       ...

       end 包名;

    例子:

     create or replace package body pack_age

      procedure pro_emp(e_no number,e_name out varchar2,e_sal out number)

      is

      begin

       select ename,sal into e_name,e_sal from emp where empno = e_no;

      end pack_emp;

 

      function fun_sal(e_deptno number) return number

      is

       v_sal number;

      begin

       select max(sal) into v_sal from emp where deptno = e_deptno;

       return v_sal;

      end fun_sal;

     end pack_age;

  3. 程序包中的子程序的引用

    包名.子程序名

  4. 引用游标的使用(ref游标):可以使用引用游标来返回一个查询的结果集

   使用步骤:

   (1)定义一个引用游标类型

     type 类型名 is ref cursor;

   (2)在存储过程中使用out参数将游标类型返回

     参数名 out 包名.游标类型名;

   (3)在存储过程实现的时候,将查询结果放入到引用游标的输出参数中

     open 参数名 for select 查询语句;

   (4)在调用存储过程的时候,也需要定义引用类型的游标对输出参数进行接受

 

   编写规范:

    create or replace package pack_emp

    is

     type ref_cur is ref cursor;

     procedure pro_emp(d_no number,row_emp out pack_emp.ref_cur);

    end pack_emp;

    create or replace package body pack_emp

    is

     procedure pro_emp(d_no number,row_emp out pack_emp.ref_cur);

     is

     begin

      open row_emp for select * from emp where deptno = d_no;

     end pro_emp;

    end pack_emp;

   调用:

    declare

     r_emp pack_emp.ref_cur;

     row_e emp%rowtype;

    begin

     pack_emp.pro_emp(30,r_emp);

     loop

      fetch r_emp into row_e;

      exit when r_emp %notfound;

       dbms_output.put_line(row_e.ename||','||row_e.sal);

     end loop;

    end;

六. 定时任务调度

  Oracle中可以在系统中设置一些定时任务,并且规定好执行的时间,然后系统会自动去执行该操作

  Oracle数据库中定时任务的操作需要使用一个程序包:dbms_job:

  1. 设置定时任务

   dbms_job.submit(

    job out number,   --定时任务生成的编号

    what in varchar2,   --设置定时任务要执行的存储过程

    next_date in date,  --设置任务下一次执行的时间

    interval in varchar2   --设置任务执行的时间间隔

   )

   例子:每隔1分钟向数据库添加一条数据

    create sequence test_pk nocache;

    create or replace procedure pro_insert_user

    is

    begin

     insert into user_t values(test_pk.nextnvl,'小明');

     commit;

    end pro_insert_user;

    

    declare

     jobid number;

    begin

     dbms_job.submit( job=>jobid,what=>'pro_insert_user;',next_date=>sysdate,interval=>'sysdate+(1/24/60)');

     dbms_output.put_line(jobid);

    end;

  2.查询系统中当前的所有定时任务

   数据字典:dba_jobs

   select * from dba_jobs;

   注意:只能在管理员模式下进行查询

  3.禁用/启用定时任务

   dbms_job.broken(任务编号,true/false);

  4.删除定时任务

   dbms_job.remove(任务编号);

   注意删除定时任务之前先将定时任务禁用

标签:存储,end,函数,sal,number,emp,Oracle,out
来源: https://www.cnblogs.com/LuoYB/p/16359649.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有