存储过程procedure

  被内容来自《oracle从入门到精通——明日科技》一书

  存储过程是一种命名的PL/SQL程序快,存储过程被保存在数据库中,它不可以被SQL语句直接执行或调用,只能通过EXECUT命令执行或在PL/SQL程序快中内部调用。由于存储过程是已经编译好的代码,所以在被调用或引用时,其执行效率非常高。本次所有操作均在Oracle 18c本版。

1.创建存储过程

  1.1.创建存储过程的语法

    使用关键字create、procedure,关键字后面时过程名字和参数列表,其基本语法如下: 

create [or replace] procedure pro_name [(parameter1 [,parameter2]...)] is|as
begin
plsql_sentences;
[exception]
[dowith_sentences;]
end [pro_name];

    1.1.1.pro_name:存储过程的名字。如果数据库存在该名字,可以加上or replace ,这样新的存储过程就会覆盖掉原来已经存在的存储过程。

    1.1.2.parameter1:存储过程的参数。如果输入参数则需要在后面使用in关键字,如果输出参参数则在后面使用out关键字。in和out关键字后面时参数的类型,不能指定参数类型的长度。

    1.1.3.plsql_sentences:PL/SQL语句。它是存储过程实现的主体。

    1.1.4.dowith_sentences:异常处理语句。也是PL/SQL语句,可以没有。

    1.1.5.在创建存储过程中IS关键字也可以用AS代替,效果是一样的。

  1.2.下面通过一个实际例子来解释如何创建一个存储过程。

    假如有一个表:

create teble t_user(
t_name varchar2(20) not null,
t_address varchar2(100) not null
)tablespace low_data;

    下面创建一个存储过程,向表user插入数据:

create procedure add_data_to_user is
begin
insert into user (t_name,t_address) values ('tony','shanghai');--插入数据的sql语句,存储过程的实体
commit;--提交事务
dbms_output.put_line('新插入数据成功!');--插入数据成功返回的信息提示,可以没有
end add_data_to_user;

    上面的存储过程为:向表user插入一条记录,存储过程的名字是add_data_to_user。如果在当前模式下数据库已经存在名为add_data_to_user的存储过程,则使用or replace关键字创建,如下:

create or replace procedure add_data_to_user is
begin
insert into user (t_name,t_address) values ('simth','beijing');--插入数据的sql语句,存储过程的实体
commit;--提交事务
dbms_output.put_line('新插入数据成功!');--插入数据成功返回的信息提示,可以没有
end add_data_to_user;

    这样就会覆盖之前创建的同名的存储过程。如果不存在则为直接创建名为add_data_to_user的存储过程。

    如果创建的过程中出现的错误,用户可以使用'show error'命令查看错误信息。

    上面的存储过程主体inert语句仅仅是被编译了,并没有执行,下面说一下如何执行。

  1.3.执行存储过程

    在SQL*Plus环境下,执行存储过程使用关键字execute命令执行存储过程的名字即可,语句如下:

execute add_data_to_user;

    在PL/SQL中执行存储过程语句为:

begin
add_data_to_user;
end;

2.存储过程的关键字

  Oralce为了增强存储过程的灵活性,提供向存储过程传入参数的功能。存错过程可以接受多个参数,参数模式包括:IN、OUT、INOUT三种。

  2.1.IN模式参数

    这是一种输入型参数。参数值由调用方传入,并且只能被存储过程使用读取。这种模式是最长用的,也是默认的。

    用法:parameter_name IN paramter_type,即(参数名称 IN 参数类型)。需要注意的是参数类型不能指定长度。

    下面创建一个IN模式的存储过程:

create or replace procedure insert_data_to_user(
d_name in varchar2,--参数一
d_address in varchar2--参数二
) is
begin
insert into t_user(t_name,t_address) values(d_name,d_address);--存储过程的实体,向表中插入数据
commit;--提交事务
end;

     向存储过程传递参数有三种方式:

    2.1.1.制定名称传递

      制定名称传递是指在向存储过程传递参数时需要指定参数的名称,即参数名称在左,中间时赋值符号“=>”,右侧是参数值。其语法如下:

pro_name(parameter1=>value1[,parameter2=>value2...])      

      parameter1:参数名称。在传递参数时,这个参数名称的顺序和存储过程定义的顺序无关。
      value2:参数值。参数值的类型要和存储过程中定义的类型相兼容。
      =>:是一种新的赋值符号。
      下面是按照制定名称方式执行我们刚才创建的存储过程:

--第一种方式
SQL> begin
2 insert_data_to_user(d_name=>'张三',d_address => '上海');
3 end;
4 / PL/SQL procedure successfully completed
--第二种方式
SQL> begin
2 insert_data_to_user(d_address=>'北京',d_name => '李四');
3 end;
4 /
PL/SQL procedure successfully completed

      我们可以看到第一种方式是按照存储过程中定义的顺序传递参数的,第二种方式没有按照存储过程中定义的顺序传递参数,但都执行成功了。可以看到表中现在存在了这两个记录:

SQL> select * from t_user;

T_NAME               T_ADDRESS
-------------------- --------------------------------------------------------------------------------
张三 上海
李四 北京 SQL>

    2.1.2.按位置传递

      按指定名称传递参数时虽然直观易读,但也有缺点,就是如果参数过多时,代码就会冗余。因此我们可以采取按位置传递。但需要注意的是,采取这种方式我们要保证传递的参数值要和存储过程中定义的顺序一致。接下来我们还以

insert_data_to_user存储过程为例向中传递参数:

SQL> begin
2 insert_data_to_user('博客园 ','位置不详 ');
3 end;
4 / PL/SQL procedure successfully completed

      注意:我上面插入数据时参数值后面有个空格,我这是自己的字符集出现问题了,所以需要这样做,真实项目中不用这样做。我们查询表可以看到刚插入的数据:

SQL> select * from t_user;

T_NAME               T_ADDRESS
-------------------- --------------------------------------------------------------------------------
张三 上海
李四 北京
博客园 位置不详 SQL>

      有的时候参数过多时,我们记不住参数的类型和顺序,这时我们可以使用desc命令查看存储过程中的参数定义信息,如:

SQL> desc insert_data_to_user;
Parameter Type Mode Default?
--------- -------- ---- --------
D_NAME VARCHAR2 IN
D_ADDRESS VARCHAR2 IN

    2.1.3.混合方式传递

      混合方式就是将前面两种方式结合到一起使用。为了方便测试我们重新新建一个存储过程,具有多个参数的存储过程:

--创建表t_product
create table t_product(
p_id number not null,
p_name varchar2(50) not null,
p_count number,
p_price number,
p_area varchar2(200)
)tablespace WCH_DATA;
--添加表、字段注释
comment on table t_product is'产品/商品表 ';
comment on column t_product.p_id is '主键 ';
comment on column t_product.p_name is '产品名称 ';
comment on column t_product.p_count is '产品数量 ';
comment on column t_product.p_price is '产品价格 ';
comment on column t_product.p_area is '产品生产地区 ';
--创建Sequence
create sequence seq_product_id
minvalue 1
maxvalue 99999999999
start with 1
increment by 1
cache 20;
--创建存储过程
create or replace procedure insert_data_to_product(
d_name in varchar2,
d_count in number,
d_price in number,
d_area in varchar2
) is
begin
insert into t_product values(seq_product_id.nextval,d_name,d_count,d_price,d_area);
commit;
end;

      我们创建了一个名为:insert_data_to_product的存储过程,参数有d_name,d_count,d_price,d_area。其中表的主键id通过我们创建的序列seq_product_id产生。下面我们来通过混合方式传递参数执行这个存储过程:

SQL> begin
2 insert_data_to_product('apple',100,d_price => 5,d_area => 'china');
3 end;
4 / PL/SQL procedure successfully completed

      需要注意的是:在某个位置使用了按名称传递方式后,其后面的参数也要使用按名称传递。因为按名称传递的方式有可能已经破坏了参数原始的定义顺序。

  2.2.OUT模式

    本次我们需要用到表t_product,里面的数据为:

SQL> select * from t_product;

      P_ID P_NAME                                                P_COUNT    P_PRICE P_AREA
---------- -------------------------------------------------- ---------- ---------- --------------------------------------------------------------------------------
1 apple 100 5 china
2 汽车 20 100000 美国
3 飞机 10 65900000 美国
4 大豆 300000 2.2 巴西
5 手机 300000 3200 中国

    OUT模式是一种输出类型的参数。表示这个参数在存储过程中已经被赋值,并且可以将这个参数传递到存储过程之外的环境中去。关键字位于参数名称之后,和IN 模式相似。下面定义一个OUT模式的存储过程:

create or replace procedure get_data_from_product (
g_id in number, --声明一个输入变量参数
g_name out varchar2, --声明一个输出变量
g_count out varchar2 --声明一个输出变量
) is
begin
select p_name,p_count into g_name,g_count from t_product where p_id=g_id;--存储过程主体,根据传入的id查询产品的名字和数量
end;

    在上面的存储过程中定义了两个OUT类型的参数,因为OUT模式需要输出参数,所以定义两个参数用来接受返回值。

    2.2.1.在PL/SQL中调用OUT模式的存储过程

      这种方式需要在PL/SQL块中通过declare定义与存储过程中OUT参数相兼容的变量,如:

SQL> set serveroutput on
SQL> declare
2 var_name t_product.p_name%type;
3 var_count t_product.p_count%type;
4 begin
5 get_data_from_product(2,var_name,var_count);
6 dbms_output.put_line(var_name);
7 dbms_output.put_line(var_count);
8 end;
9 / 汽车
20 PL/SQL procedure successfully completed

      在这段代码中我们首先声明了两个变量var_name和var_count,变量类型要和存储过程中定义的OUT变量相兼容。然后把两个变量传入到存储过程中,当存储过程被执行时,其中out参数会被赋值,当存储过程执行完之后,OUT参数的值会在会在调用处返回。这样定义的两个变量就可以得到OUT参数被赋予的值了。

    2.2.2.使用exec命令执行OUT模式的存储过程

      使用exec命令需要在SQL*Plus环境中使用variable关键字声明两个变量,将声明的了两个变量接受OUT参数的返回值。如:

SQL> variable v_name varchar2(50);
SQL> variable v_count number;
SQL> exec get_data_from_product(3,:v_name,:v_count); PL/SQL procedure successfully completed v_name
---------
飞机
v_count
---------
10

      我们还可以使用print或者select命令来查看变量的值如:

SQL> print v_name;
v_name
---------
飞机 SQL>
SQL> print v_count;
v_count
---------
10 SQL> select :v_name,:v_count from dual; :V_NAME :V_COUNT
-------------------------------------------------------------------------------- ----------
飞机 10
v_name
---------
飞机
v_count
---------
10

ORACLE——存储过程的更多相关文章

  1. oracle 存储过程

    来自:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 I ...

  2. Oracle存储过程语法

    原文链接:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程  1 CREATE OR REPLACE PROCEDURE 存储过程名  ...

  3. ORACLE存储过程调用Web Service

    1. 概述 最近在ESB项目中,客户在各个系统之间的服务调用大多都是在oracle存储过程中进行的,本文就oracle存储过程调用web service来进行说明.其他主流数据库,比如mysql和sq ...

  4. Oracle存储过程基本语法介绍

    Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 IS 3 BEGIN 4 NULL; 5 END; 行1: CREATE OR RE ...

  5. MyBatis调用Oracle存储过程

    MyBatis调用Oracle存储过程 1.无输入和输出参数的存储过程 2.带有输入和输出参数的存储过程 3.返回游标的存储过程 mybatis中的配置文件代码 <resultMap type= ...

  6. Oracle存储过程(转)

    Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 IS 3 BEGIN 4 NULL; 5 END; 行1: CREATE OR RE ...

  7. Oracle存储过程中异常Exception的捕捉和处理

    Oracle存储过程中异常的捕捉和处理 CREATE OR REPLACE Procedure Proc_error_process ( v_IN in Varchar2, v_OUT Out Var ...

  8. Oracle存储过程动态创建临时表/存储过程执行权限问题--AUTHID CURRENT_USER

    关于Oracle存储过程执行权限问题的解决 http://blog.sina.com.cn/s/blog_6ceed3280101hvlo.html (2014-04-02 04:06:28) 转载▼ ...

  9. ORACLE存储过程学习

    存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 IS 3 BEGIN 4 NULL; 5 END; 行1: CREATE OR REPLACE PROCEDURE ...

  10. C# 获取 oracle 存储过程的 返回值1

    /// <summary> /// 返回对应表的模拟自增字段值 /// </summary> /// <param name="tablename"& ...

随机推荐

  1. 【转载】基于rasa的对话系统搭建(上)

    文章介绍使用rasa nlu和 rasa core 实现一个电信领域对话系统demo,实现简单的业务查询办理功能,更完善的实现需要进一步数据的收集.demo基于玩具数据集,可以达到下面的效果: Bot ...

  2. RSA/SHA1加密和数字签名算法在开放平台中的应用

    加密算法 加密算法分为两大类:1.对称加密算法:2.非对称加密算法.   密钥个数 加密 解密 对称加密 一个 使用密钥加密 使用同一个密钥解密 非对称加密 两个,公钥和私钥 使用其中一把密钥加密 使 ...

  3. redhat 7.5 更换 yum源

    因为 redhat 的 yum 是收费,所以需要换成 Centos 的 yum 才可以 首先,卸载 redhat 的 yum 软件 sudo rpm -qa|grep yum 其次,下载 Centos ...

  4. GeForce GTX 1080 ti安装记录

    安装GeForce GTX 1080ti 安装GeForce GTX 1080ti,8+8pin需要全接,接4pin就开机显示器上会提示电源线没接完,将显示器线接在显卡上. 设置Win 10 pro ...

  5. golang加油!

  6. SpirngBoot之整合Swagger2

    前言 swagger,中文"拽"的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅, 而且还提供了在线文档的测试.另外swagger很容易构建rest ...

  7. 浅从System.Web.Http.Owin的HttpMessageHandlerAdapter看适配器模式

    本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.写在前面 适配器模式(Adapter) 可用来在现有接口和不兼容的类之间进行适配.有助于 ...

  8. EnumUtil 链表转换工具类

    package com.das.common.util; import org.springframework.util.CollectionUtils; import java.lang.refle ...

  9. 离屏Canvas — 使用Web Worker提高你的Canvas运行速度

    离屏Canvas — 使用Web Worker提高你的Canvas运行速度 原文链接: developers.google.com 现在因为有了离屏Canvas,你可以不用在你的主线程中绘制图像了! ...

  10. Linux服务器性能分析与调优

    一 linux服务器性能查看 1.1 cpu性能查看 1.查看物理cpu个数: cat /proc/cpuinfo |grep "physical id"|sort|uniq|wc ...