说明:SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML, 数据定义语言DDL,数据控制语言DCL。

0.调试

点击procedure名,右键选择调试。即可进入调试模式。找到procedure,点击右键,查看,可看到编译错误信息。

Dbms_output.Put_line('打印内容:' || v_total); --打印

  v_str:=&dno; 其中 &表示键盘输入。即接收键盘输入的值dno表示Name。

1.基本用法

  查看所有的存储过程:

  select object_name,object_type,status from user_objects where OBJECT_TYPE='PROCEDURE';

  查看某个存储过程:

  SELECT text FROM user_source WHERE NAME = 'procedure_name';

  删除:

  drop procedure procedure_name;

  新增:

  create or replace procedure procedure_name;

CREATE OR REPLACE PROCEDURE test1 IS
v_total NUMBER;
BEGIN
SELECT COUNT(*) INTO v_total FROM user;
Dbms_output.Put_line(v_total);  --打印
END;
 存储过程创建语法:

create or replace procedure procedure_name(param1 in type,param2 out type,param3 in out type) --参数类型不需要定义值范围

 as

 变量1 类型(值范围);

 变量2 类型(值范围);

 Begin
...........
END [procedure_name];
 begin
execute immediate 'ALTER TABLE RECORD_XWZX5_left ADD (ID NUMBER)';
execute immediate 'ALTER TABLE RECORD_XWZX5_right ADD (ID NUMBER)';
update RECORD_XWZX5_right set ID = ROWNUM;
update RECORD_XWZX5_left set ID = ROWNUM;
commit;
end ; 执行多条插入语句

1.  其中的 IS 可以用 AS来替代,两个是同义词。(oracle数据库表名不能用as)

    在视图(VIEW)中只能用AS不能用IS

    在游标(CURSOR)中只能用IS不能用AS

2.     Select 必须有 INTO 接收值的变量(select ** into v_name ),不然报错,在赋值时最好用count(*)测试下,是否有多值和无值的情况发生,在Exception中处理结果。

调用:

// pLsql调用
BEGIN
test1();
END; // 外部程序调用
[EXECUTE]|[CALL] procedure_name[(parameter,…n)]

2. 变量

DECLARE v1 hr_user.oa_name%TYPE;

赋值:

v1:='zhangsan';

v_count INT :=30;

声明时不能够赋值,只能default形式设定默认值。

3.参数

存储过程的参数不用带取值范围直接定义类型即可,且形式只有IN和OUT两种,或者将两个都共存。

CREATE OR REPLACE PROCEDURE test1(v1 in varchar, v2 out varchar,v3 in out varchar) 默认为IN形式。

 /* 创建 */
CREATE OR REPLACE PROCEDURE test1(v1 VARCHAR, v2 OUT INT) IS
BEGIN
SELECT COUNT(*) INTO v2 FROM user WHERE name = v1;
Dbms_output.Put_line(v2);
EXCEPTION
WHEN NO_DATA_FOUND THEN
v2 := 0;
Dbms_output.Put_line(v2);
WHEN OTHERS THEN
ROLLBACK;
END; /* 调用 */
DECLARE v1 VARCHAR(100);
v2 INT;
BEGIN
v1:='zhangsan';
test1(v1, v2);
END;

另一种声明变量参数的方式%type。

%type 表示将参数的类型和表中的某个字段绑定,使用字段定义的参数类型。这样当参数类型变化时,存储过程中的跟着变化。

CREATE OR REPLACE PROCEDURE test1(v1 user.name%TYPE, v2 OUT INT) IS

PROCEDURE APPS.TEST1 编译错误 错误:PLS-00363: 表达式 'V_INCREMENT' 不能用作赋值目标 In out 被作为了常量,因此不能够被赋值,只能获取。

默认传参:

默认存储过程传参是按照前后顺序进行,

test1(va,vb);

如果不按照前后顺序,则使用以下方式:

 DECLARE
va hr_user.oa_name%TYPE;
ve INT;
BEGIN
va:='zhangsan';
test1(v1 =>va, v2 =>ve);
END;

4.raise ***主动抛出异常

 CREATE OR REPLACE PROCEDURE test1(v1 VARCHAR, v2 OUT INT) IS
BEGIN
SELECT COUNT(*) INTO v2 FROM user WHERE name = v1;
Dbms_output.Put_line(v2);
IF v2 > 1 THEN
RAISE TOO_MANY_ROWS;
ELSIF v2 = 0 THEN
RAISE NO_DATA_FOUND;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v2 := 0;
Dbms_output.Put_line('未查询到任何数据');
WHEN TOO_MANY_ROWS THEN
Dbms_output.Put_line('返回多行数据');
WHEN OTHERS THEN
ROLLBACK;
END;

命名的系统异常                          产生原因

ACCESS_INTO_NULL                   未定义对象

CASE_NOT_FOUND                     CASE 中若未包含相应的 WHEN ,并且没有设置

ELSE 时

COLLECTION_IS_NULL                集合元素未初始化

CURSER_ALREADY_OPEN          游标已经打开

DUP_VAL_ON_INDEX                   唯一索引对应的列上有重复的值

INVALID_CURSOR                 在不合法的游标上进行操作

INVALID_NUMBER                       内嵌的 SQL 语句不能将字符转换为数字

NO_DATA_FOUND                        使用 select into 未返回行,或应用索引表未初始化的

TOO_MANY_ROWS                      执行 select into 时,结果集超过一行

ZERO_DIVIDE                              除数为 0

SUBSCRIPT_BEYOND_COUNT     元素下标超过嵌套表或 VARRAY 的最大值

SUBSCRIPT_OUTSIDE_LIMIT       使用嵌套表或 VARRAY 时,将下标指定为负数

VALUE_ERROR                             赋值时,变量长度不足以容纳实际数据

LOGIN_DENIED                           PL/SQL 应用程序连接到 oracle 数据库时,提供了不

正确的用户名或密码

NOT_LOGGED_ON                       PL/SQL 应用程序在没有连接 oralce 数据库的情况下

访问数据

PROGRAM_ERROR                       PL/SQL 内部问题,可能需要重装数据字典& pl./SQL

系统包

ROWTYPE_MISMATCH                宿主游标变量与 PL/SQL 游标变量的返回类型不兼容

SELF_IS_NULL                             使用对象类型时,在 null 对象上调用对象方法

STORAGE_ERROR                        运行 PL/SQL 时,超出内存空间

SYS_INVALID_ID                         无效的 ROWID 字符串

TIMEOUT_ON_RESOURCE         Oracle 在等待资源时超时

6. 流程结构控制

 IF: if 条件 then

else

end if

----------------------

if 条件 then

elsif 条件 then

end if

这里中间是“ELSIF”,而不是ELSE IF 。这里需要特别注意

WHILE:

WHILE ... LOOP

[BEGIN]

[END];

END LOOP;

 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
v_count INT := ;
v_icre INT DEFAULT v_increment;
BEGIN
WHILE v_icre < v_count LOOP
BEGIN --可加可不加
Dbms_output.Put_line('打印内容:' || v_icre);
v_icre := v_icre + ;
END;
END LOOP;
END TEST1;

7. 游标cursor使用

cursor 只能用IS修饰。

注意:因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;游标类型:隐式游标和显式游标。
      隐式游标:DML(数据操作语言包括:INSERT,DELETE,UPDATE,SELECT... INTO 等单行语句) SQL语句都会使用隐式游标调用。
属性 返回值类型 说明
SQL%ROWCOUNT 整型 代表DML语句成功执行的数据行数
SQL%FOUND 布尔型 TRUE代表插入、删除、更新或单行查询操作成功
SQL%NOTFOUND 布尔型 与SQL%FOUND属性返回值相反
SQL%ISOPEN 布尔型 DML执行过程中为真,结束后为假

显式游标:DQL(查询语句select) sql返回多行数据时,使用显式游标调用。

    %Found :Fetch语句(获取记录)执行情况True or False。
%NotFound : 最后一条记录是否提取出True or False。
%ISOpen : 游标是否打开True or False。
%RowCount :游标当前提取的行数 。

定义:   CURSOR cur IS SELECT * FROM user;

传参:   v_cur cur%rowType;一行数据类型

 FOR循环游标隐式打开游标,自动滚动获取一条记录,并自动创建临时记录类型变量存储记录。处理完后自动关闭游标。
fetch ... into ... 游标开始在空行,使用fetch into 使得游标进入下一行
注意: 只是要注意用更新游标的时候,不能在游标期间commit. 否则会报
ORA-01002: fetch out of sequence
      就是COMMIT;导致错误
       在打开有for update的cursor时,系统会给取出的数据加上排他锁(exclusive),
       这样在这个锁释放前其他用户不能对这些记录作update、delete和加锁。
       而我一旦执行了commit,锁就释放了,游标也变成无效的,再去fetch数据时就出现错误了。
       因而要把commit放在循环外,等到所有数据处理完成后再commit,然后关闭cursor

使用(for ... in  ... loop .... end loop直接开始游标):

    for  cur_result in cur loop

      v_name:=cur_result.column_name;

    end loop;

 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
v_name VARCHAR();
v_type VARCHAR();
CURSOR cur IS
SELECT * FROM user WHERE rownum < ;
BEGIN
FOR cur_result IN cur LOOP
v_name := cur_result.name;
v_type := cur_result.type;
Dbms_output.Put_line('打印内容:' || v_name || ' ' || v_type);
END LOOP;
END TEST1;

使用2(loop fetch cur into ...):

 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
v_name VARCHAR();
v_type VARCHAR();
CURSOR cur IS
SELECT name, type FROM user WHERE rownum < ;
BEGIN
OPEN cur;
LOOP
FETCH cur
INTO v_name, v_type;
EXIT WHEN cur%NOTFOUND;
BEGIN
Dbms_output.Put_line('打印内容:' || v_name || ' ' || v_type);
END;
END LOOP;
CLOSE cur;
END TEST1;

使用3(while):

 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
v_name VARCHAR();
v_type VARCHAR();
CURSOR cur IS
SELECT name, type FROM user WHERE rownum < ;
v_row cur%ROWTYPE; --变量定义必须在begin之前
BEGIN
OPEN cur;
FETCH cur INTO v_row; --fetch将值赋予v_row
WHILE cur%FOUND LOOP
Dbms_output.Put_line('打印内容:' || v_row.name || ' ' ||
v_row.type);
FETCH cur INTO v_row;
END LOOP;
CLOSE cur;
END TEST1;

4.游标带参

 CREATE OR REPLACE PROCEDURE TEST1(v_oname IN VARCHAR) IS
v_name VARCHAR(100);
v_type VARCHAR(100);
CURSOR cur(v_name1 VARCHAR) IS
SELECT name, type FROM user
WHERE name = v_name1
AND rownum < 50;
v_row cur%ROWTYPE;
BEGIN
OPEN cur(v_oname);
FETCH cur
INTO v_row;
WHILE cur%FOUND LOOP
Dbms_output.Put_line('打印内容:' || v_row.name || ' ' ||
v_row.type);
FETCH cur
INTO v_row;
END LOOP;
CLOSE cur;
END TEST1;

5. 游标更新和删除

CURSOR cursor_name IS select_statement
FOR UPDATE [OF column_reference] [NOWAITE]; -- OF子句指定对特定表加锁。
UPDATE table_name SET column=.. WHERE CURRENT OF cursor_name;
DELETE table_name WHERE CURRENT OF cursor_name;

6.批量提取

  FETCH ... BULK COLLECT INTO ...[LIMIT row_number];

 CREATE OR REPLACE PROCEDURE TEST1(v_oname IN VARCHAR) IS
v_name VARCHAR(100);
v_type VARCHAR(100);
CURSOR cur IS
SELECT *
FROM user
WHERE name LIKE '%' || v_oname || '%'
AND rownum < 50;
v_row cur%ROWTYPE; TYPE type_user IS TABLE OF user%ROWTYPE INDEX BY BINARY_INTEGER;
user_table type_user;
BEGIN
OPEN cur;
FETCH cur BULK COLLECT
INTO user_table limit 5;
CLOSE cur;
FOR i IN 1 .. user_table.count LOOP
Dbms_output.Put_line('打印内容:' || user_table(i).name || ' ' || user_table(i) .type);
END LOOP;
END TEST1;

参考:

Oracle存储过程创建及调用(http://www.cnblogs.com/chinafine/articles/1776094.html)

Oracle存储过程学习(http://www.cnblogs.com/chuncn/archive/2009/01/29/1381291.html)

Oracle游标使用全解(http://blog.csdn.net/jeathenzhang/article/details/8853607)

plsql游标详解(http://blog.csdn.net/kb5706/article/details/7575445)

Procedure-Function oracle的更多相关文章

  1. MySQL:procedure, function, cursor,handler

    Procedure & Function Procedure 语法: CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ...

  2. oracle 备份数据库对象(存储过程PROCEDURE,FUNCTION,VIEW,TRIGGER...)

    开发过程中,需要不停的备份数据库对象, 特别是存储过程, 每次手动备份不免很低能啊 历经几次修改终于, 完美了,O(∩_∩)O哈哈~      (当然,你也可以再改简便一点~~~) select db ...

  3. [转]Easy Stored Procedure Output Oracle Select

    本文转自:http://www.oraclealchemist.com/oracle/easy-stored-procedure-output/ I answered a question on a ...

  4. What is the difference between routine , method , procedure , function ? please explain it with example?

    a method is named and attached to an object. so, for example, a method is like a function but is con ...

  5. [转]MONTHS_BETWEEN Function - Oracle to SQL Server Migration

    本文转自:http://www.sqlines.com/oracle-to-sql-server/months_between In Oracle, MONTHS_BETWEEN(date1, dat ...

  6. 通过PLSQL创建Database link,DBMS_Job,Procedure,实现Oracle跨库传输数据

    前一阵领导安排了一个任务:定时将集团数据库某表的数据同步至我们公司服务器的数据库,感觉比写增删改查SQL有趣,特意记录下来,希望能帮到有类似需求的小伙伴,如有错误也希望各位不吝指教 环境描述: 集团数 ...

  7. 存储过程和函数 PROCEDURE & FUNCTION

    SQL语句执行的时候,要首先编译,然后在被执行.在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行. 具体而言 ...

  8. 修改Mysql procedure,function and view definer

    1 一次性修改遇到错误 update mysql.proc set definer='root@%'; update mysql.proc set definer='root@%'; ERROR 10 ...

  9. 移植Oracle procedure 到 postgresql

    1.登录postgresql psql -h 192.168.137.131 -p 5432 postgres satusc@6789#JKL 2.创建用户 CREATE USER name thun ...

  10. Oracle procedure 基本语法

    转自:http://lorry1113.javaeye.com/blog/513851 关键字: oracle 存储过程 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程 ...

随机推荐

  1. day9 python学习 文件的操作 读 写 seek

    文件的操作 1   文件的打开操作: 文件句柄 = open('文件路径', '模式') f=open('wangyakun','a+',encoding='utf-8') #文件名, 如果是绝对路径 ...

  2. 总结:基于Oracle Logminer数据同步

    第 1 页 共 20 页 出自石山园主,博客地址:http://www.cnblogs.com/shishanyuan LogMiner 配置使用手册 1 Logminer 简介 1.1 LogMin ...

  3. JUC集合之 ConcurrentLinkedQueue

    ConcurrentLinkedQueue介绍 ConcurrentLinkedQueue是线程安全的队列,它适用于"高并发"的场景. 它是一个基于链接节点的无界线程安全队列,按照 ...

  4. mysql ssh 端口转发

    某些时候 mysql  只允许 指定的 ip连接 .这时候怎么在本机 连接mysql 的呢? 条件 1 mysql 只有 允许 指定ip连接 2 有连接 指定 ip 服务器的  账密 这时候我们可以通 ...

  5. Ionic 中MD5加密使用

    1. 下载安装ts-md5 在项目的命令行工具里输入 npm  install ts-md5 --save 2. 使用 导入 import {Md5} from "ts-md5/dist/m ...

  6. 大数据应用之HBase数据插入性能优化实测教程

    引言: 大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题.事实胜于雄辩,数据比理论更有说服力,基于此,作者设计 ...

  7. 服务注册发现Eureka之三:Spring Cloud Ribbon实现客户端负载均衡(客户端负载均衡Ribbon之三:使用Ribbon实现客户端的均衡负载)

    在使用RestTemplate来消费spring boot的Restful服务示例中,我们提到,调用spring boot服务的时候,需要将服务的URL写死或者是写在配置文件中,但这两种方式,无论哪一 ...

  8. ASP.NET Web Pages:WebMail 帮助器

    ylbtech-.Net-ASP.NET Web Pages:WebMail 帮助器 1.返回顶部 1. ASP.NET Web Pages - WebMail 帮助器 WebMail 帮助器 - 众 ...

  9. Hive基础之Hive表常用操作

    本案例使用的数据均来源于Oracle自带的emp和dept表 创建表 语法: CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name ...

  10. MapReduce On YARN

    MapReduce计算框架 将计算过程分为两个阶段:Map和Reduce Map阶段并行处理输入数据: Reduce阶段对Map结果进行汇总 Shuffle连接Map和Reduce两个阶段 Map T ...