说明: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. prisma 服务器端订阅试用

      graphql 协议是支持数据的实时订阅功能的(一般基于websocket 进行实现) prisma 支持客户端订阅以及服务器端订阅(类似webhook),可以方便将 数据推送后端服务 目的 pr ...

  2. Python自动发邮件——smtplib和email库和yagmail库

    ''' 一.先导入smtplib模块 导入MIMEText库用来做纯文本的邮件模板 二.发邮件几个相关的参数,每个邮箱的发件服务器不一样,以163为例子百度搜索服务器是 smtp.163.com 三. ...

  3. 解决python2安装MySQL-python模块报错

    今天电脑重装系统,所有软件都重装一遍,MySQLdb模块一直装不好,纠结了好久,终于解决,方法分享给大家. MySQLdb模块安装: 1.下载MySQL-pyhon模块,网站为:https://pyp ...

  4. hadoop 知识点

    HDFS 命令 命令 说明 fsck 检查文件的完整性 start-balancer.sh 重新平衡HDFS hdfs dfs -copyFromLocal 从本地磁盘复制文件到HDFS hadoop ...

  5. js的模块化规范

    js的模块化规范常见的有:AMD,CMD,commonJS,UMD,es6 前期在没有模块化的时候,js文件十分庞大,于是就按功能抽离划分为多个js文件. 但是在html页面通过script的方式加载 ...

  6. python初始环境安装

    Python下载地址 Python官网:https://www.python.org/ 在该网可以下载Python最新及历史版本.可以下载基于Windows或其它操作系统的版本. Python安装 本 ...

  7. 在启动Windows Process Activation Service时,出现错误13:数据无效

    在启动Windows Process Activation Service时,出现错误13:数据无效 1.错误原因: 当Windows Process Activation Service从C:\Wi ...

  8. AppScan代理扫描app/H5安全测试(没试过,记录在此)

    标签: 1.首先设置AppScan代理,设置如下:

  9. Java中的yield关键字的简单讲解

    Thread.yield()方法作用是:暂停当前正在执行的线程对象,并执行其他线程. yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会.因此,使用yie ...

  10. Logistic回归的两种形式y=0/1,y=+1/-1

    第一种形式:y=0/1 第二种形式:y=+1/-1 第一种形式的损失函数可由极大似然估计推出: 第二种形式的损失函数:  , 参考:https://en.wikipedia.org/wiki/Loss ...