PL/SQL — 存储过程
存储过程子程序的一种类型,能够完成一些任务,作为schema对象存储于数据库。是一个有名字的PL/SQL代码块,支持接收或不接受参数,同时也支持参数输出。一个存储过程通常包含定于部分,执行部分,Exception部分,可以被其他子程序调用,也可以被重用。
一、过程定义
CREATE [OR REPLACE]PROCEDURE procedure_name
[(argument_name [IN | OUT | IN OUT] argument_type)]
AS | IS
BEGIN
procedure_body;
END [procedure_name];
存储过程中参数的类型
IN:表示是一个输入参数,可以指定缺省值。如省略参数类型,则缺省为in类型
OUT:表示是一个输出参数
IN OUT:既可以作为一个输入参数,也可以作为一个输出参数来输出结果
二、过程调用
EXECUTE |CALL procedure_name [(argument_list)]
--例:定义一个过程,以JOB为参数,查询该JOB的最高工资、最低工资、平均工资。
CREATE OR REPLACE PROCEDURE display_sal(v_job emp.job%TYPE) --该形参缺省为in类型,数据类型为emp.job%TYPE
AS
v_avg_sal emp.sal%TYPE;
v_max_sal emp.sal%TYPE;
v_min_sal emp.sal%TYPE;
BEGIN
SELECT avg(sal) INTO v_avg_sal FROM emp WHERE job=v_job;
SELECT max(sal) INTO v_max_sal FROM emp WHERE Job=v_job;
SELECT min(sal) INTO v_min_sal FROM emp WHERE job=v_job;
DBMS_OUTPUT.PUT_LINE('DEPT '||v_job||' avg sal:'||v_avg_sal);
DBMS_OUTPUT.PUT_LINE('DEPT '||v_job||' max sal:'||v_max_sal);
DBMS_OUTPUT.PUT_LINE('DEPT '||v_job||' min sal:'||v_min_sal);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NOT FOUND RECORD!');
END display_sal;
/
scott@ORCL> set serveroutput on;
scott@ORCL> exec display_sal('SALESMAN');
DEPT SALESMAN avg sal:1400
DEPT SALESMAN max sal:1600
DEPT SALESMAN min sal:1250
PL/SQL procedure successfully completed.
三、参数及其传递方式:
在建立过程时,传递的参数为可选项,如果省略参数选项,则过程为无参过程(定义时不指定参数,调用时也不需要参数)。
如果指定参数选项,则过程为有参过程(定义时需要指定参数名字、模式、数据类型,调时时需要给出对应的参数值),定义时的参数,称为形参,调用时的参数称为实参。
1.无参过程
CREATE OR REPLACE PROCEDURE display_systime
AS
BEGIN
DBMS_OUTPUT.PUT_LINE('CURRENT TIME IS '||sysdate);
END display_systime;
/
execute display_systime; --调用
2.有参过程
定义时需要指定参数的名字、模式、数据类型
--例:定义一个添加记录的过程(全部为输入参数)
CREATE OR REPLACE PROCEDURE add_emp
(
v_no IN emp.empno%TYPE,
v_name IN emp.ename%TYPE,
v_dept IN emp.deptno%TYPE default 20 --此过程中指定了缺省的输入值,即部门号为
)
AS
BEGIN
INSERT INTO emp (empno,ename,deptno) VALUES (v_no,v_name,v_dept);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Record Is Exist!');
END add_emp;
/
execute add_emp(8000,'TEST2',20); --调用
--例:定义一个输入员工编号,修改记录,再返回修改后的结果(姓名和工资)。
CREATE OR REPLACE PROCEDURE ed_emp
(
v_no IN emp.empno%TYPE, --定义了一个in类型,二个out类型的参数
v_name OUT emp.ename%TYPE,
v_sal OUT emp.sal%TYPE
)
AS
BEGIN
UPDATE emp SET sal=sal+100 WHERE empno=v_no;
SELECT ename,sal INTO v_name,v_sal FROM emp WHERE empno=v_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('NOT FOUND RECORD!');
END ed_emp;
/
scott@ORCL> VARIABLE t_name varchar2(20);
scott@ORCL> VARIABLE t_sal number;
scott@ORCL> call ed_emp(7788,:t_name,:t_sal);
Call completed.
scott@ORCL> print t_name t_sal;
T_NAME
--------------------------------
SCOTT
T_SAL
----------
3100
--例:IN OUT类型参数的使用
CREATE OR REPLACE PROCEDURE comp
(num1 IN OUT NUMBER,num2 IN OUT NUMBER)
AS
v1 NUMBER;
v2 NUMBER;
BEGIN
v1:=num1+num2;
v2:=num1*num2;
num1:=v1;
num2:=v2;
END;
/
scott@ORCL> var n1 number;
scott@ORCL> var n2 number;
scott@ORCL> exec :n1:=5;
scott@ORCL> exec :n2:=3;
scott@ORCL> exec comp(:n1,:n2);
scott@ORCL> print n1 n2;
N1
----------
8
N2
----------
15
存储过程参数的传递方式:
按位置传递:
实参按顺序将值传给形参
EXECUTE ED_EMP(7900,:t_name,:t_sal);
EXECUTE ED_EMP(8000,'TEST2',20);
按名字传递:
EXECUTE ED_EMP(v_name=>'ABCDE',v_dept=>10,v_no=>8003);
混合传递:
EXECUTE ED_EMP(8005,v_dept=>20,v_name=>'TEST5');
注意host variable 的使用
host 变量指的是一个绑定变量,也称之为全局变量
host 变量通常在存储过程之外被声明,如SQL*Plus使用variable来声明或使用Java来声明
host 变量在声明是使用variable关键字声明,如VARIABLE t_name varchar2(20)
host 变量在引用时使用:variable_name来引用该全局变量,如上面的引用为:t_name
可以被任意的匿名块调用并传入或传出数据值
四、过程管理
查看系统过程信息
DBA_OBJECTS
DBA_PROCEDURES
DBA_SOURCE
--使用desc procedure_name 查看存储过程的参数信息
scott@ORCL> desc ed_emp;
PROCEDURE ed_emp
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
V_NO NUMBER(4) IN
V_NAME VARCHAR2(10) OUT
V_SAL NUMBER(7,2) OUT
--从dba_objects获得存储过程的信息
idle> select owner,object_name,object_type,status from dba_objects where object_name = 'ED_EMP';
OWNER OBJECT_NAME OBJECT_TYPE STATUS
------------------------------ -------------------- --------------- -------
SCOTT ED_EMP PROCEDURE VALID
scott@ORCL> select object_name,procedure_name,interface,authid from user_procedures;
OBJECT_NAME PROCEDURE_NAME INT AUTHID
-------------------- ------------------------------ --- ------------
DISPLAY_SAL NO DEFINER
ED_EMP NO DEFINER
--查看存储过程的源代码
scott@ORCL> select line, text from user_source where name='ED_EMP';
LINE TEXT
---------- --------------------------------------------------------------------------------
1 PROCEDURE ed_emp
2 (
3 v_no IN emp.empno%TYPE,
4 v_name OUT emp.ename%TYPE,
5 v_sal OUT emp.sal%TYPE
6 )
7 AS
8 BEGIN
9 UPDATE emp SET sal=sal+100 WHERE empno=v_no;
10 SELECT ename,sal INTO v_name,v_sal FROM emp WHERE empno=v_no;
11 EXCEPTION
12 WHEN NO_DATA_FOUND THEN
13 DBMS_OUTPUT.PUT_LINE('NOT FOUND RECORD!');
14 END ed_emp;
--查看错误信息
SHOW ERRORS
scott@ORCL> CREATE OR REPLACE PROCEDURE comp
2 (num1 IN OUT NUMBER,num2 IN OUT NUMBER)
3 AS
4 v1 NUMBER;
5 v2 NUMMBER;
6 BEGIN
7 v1:=num1+num2;
8 v2:=num1*num2;
9 num1:=v1;
10 num2:=v2;
11 END;
12 /
Warning: Procedure created with compilation errors.
scott@ORCL> show errors;
Errors for PROCEDURE COMP:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/4 PL/SQL: Item ignored
5/4 PLS-00201: identifier 'NUMMBER' must be declared
8/3 PL/SQL: Statement ignored
8/3 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
10/3 PL/SQL: Statement ignored
10/9 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
删除过程
DROP PROCEDURE procedure_name
scott@ORCL> drop procedure comp;
Procedure dropped.
[摘自乐沙弥的世界]
PL/SQL — 存储过程的更多相关文章
- PL/SQL存储过程编程
PL/SQL存储过程编程 /**author huangchaobiao *Email:huangchaobiao111@163.com */ PL/SQL存储过程编程(上) 1. Oracle应用编 ...
- PL/SQL 存储过程
PL/SQL复习九 存储过程 无参数的存储过程: create or replace procedure out_time is begin dbms_output.put_line(to_char( ...
- pl/sql 存储过程执行execute immediate 卡住
在存储过程中,执行了create table.update table.insert into table 但是在使用pl/sql的存储过程调试的时候,一有问题就直接卡住(标识:执行中.....) 后 ...
- 关于oracle PL/SQL存储过程 PLS-00905 object is invalid,statement ignored问题的解决
昨天在学习oracle存储过程的时候,写了一个存储过程的demo,语句是这样的: )) AS psssal TESTDELETE.TESTID%TYPE; BEGIN SELECT TESTID IN ...
- PL/SQL存储过程
一.概述 过程和函数统称为PL/SQL子程序,他们是被命名的PL/SQL块,均存储于数据库中. 并通过输入.输出和输入输出参数与其调用者交换信息.唯一区别是函数总向调用者返回数据. 二.存储过程详解 ...
- Oracle笔记 十、PL/SQL存储过程
--create or replace 创建或替换,如果存在就替换,不存在就创建 create or replace procedure p is cursor c is select * from ...
- oracle pl/sql 存储过程
存储过程用于执行特定的操作,当建立存储过程时,既可以指定输入参数(in),也可以指定输出参数(out),通过在过程中使用输入参数,可以将数据传递到执行部分:通过使用输出参数,可以将执行部分的数据传递到 ...
- pl sql 存储过程 执行sql 锁死状态
背景 这是在一个不知如何表达的项目中,我在这个项目中做的就是不知如何表达的事情.只是想着技术,到是通过这个项目把存储过程基本能用的都用了,oracle开发的技术我感觉基本都全活了.别人没搞定的我搞定了 ...
- Oracle数据库--PL/SQL存储过程和函数的建立和调用
1.存储过程建立的格式: create or replace procedure My_Procedure is begin --执行部分(函数内容); end; / 例子:(以hr表为例) crea ...
随机推荐
- mysqldump 的一些使用参数
备份数据库#mysqldump 数据库名 >数据库备份名 #mysqldump -A -u用户名 -p密码 数据库名>数据库备份名 #mysqldump -d -A --add-drop- ...
- JAVA获取CLASSPATH路径--转
ClassLoader提供了两个方法用于从装载的类路径中取得资源: public URL getResource(String name); public InputStream ge ...
- 心跳之旅—💗—iOS用手机摄像头检测心率(PPG)
[前情提要] 光阴似箭,日月如梭,最近几年,支持心率检测的设备愈发常见了,大家都在各种测空气测雪碧的,如火如荼,于是我也来凑一凑热闹.[0]这段时间,我完成了一个基于iOS的心率检测Demo,只要稳定 ...
- Java基础知识强化之多线程笔记04:并行和并发 区别
1. 并发 和 并行区别 (1)并发:(单核) 并发,是在同一个cpu上同时(不是真正的同时,而是看来是同时,因为cpu要在多个程序间切换)运行多个程序. 并发是指两个任务都请求运行,而处理器只能按受 ...
- Wireshark 过滤条件
做应用识别这一块经常要对应用产生的数据流量进行分析. 抓包采用wireshark,提取特征时,要对session进行过滤,找到关键的stream,这里总结了wireshark过滤的基本语法,供自己以后 ...
- axel源码学习(1)——重要流程细节
前面一篇文章的流程太过于简单,基本没有触及到axel的核心,因此本文将要把axel中的几个重要的主要的操作流程单独弄出来看看,还是按照main函数的执行顺序来展开,略去错误处理之类的流程仅仅着眼于最重 ...
- how to learn algorithms(ZAC)
(这一篇觉得写得很棒,故拷过来以便慢慢看,细细体会,详情请访问http://blog.csdn.net/shenmen123456/article/details/6575647) 第一阶段:练经典常 ...
- FPGA设计—UVM验证篇 Hello world
这里就不赘述UVM为何物了,做了半年多的FPGA设计验证工作,按需求一直是用VHDL编写测试程序,最近看了几天UVM验证方法学的书,感觉这是一种很好的验证工具,现在开始UVM的学习,于是准备用Mode ...
- 无责任比较thrift vs protocol buffers
http://blog.csdn.net/socoolfj/article/details/3855007 最新版本的Hadoop代码中已经默认了Protocol buffer作为RPC的默认实现,原 ...
- ViewState原理
1.IsPostBack原理 1.1 所有的服务端控件,都必须放在runat="server"的表单里面,runat="server"的表单会生成__VIEWS ...