Procedure-Function oracle

说明: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;

 1 存储过程创建语法:
 2
 3create or replace procedure procedure_name(param1 in type,param2 out type,param3 in out type) --参数类型不需要定义值范围
 4
 5 as
 6
 7 变量1 类型(值范围);
 8
 9 变量2 类型(值范围);
10
11 Begin
12 ...........
13 END [procedure_name];
1 begin
2 execute immediate ‘ALTER TABLE RECORD_XWZX5_left ADD (ID NUMBER)‘;
3 execute immediate ‘ALTER TABLE RECORD_XWZX5_right ADD (ID NUMBER)‘;
4 update RECORD_XWZX5_right set ID = ROWNUM;
5 update RECORD_XWZX5_left set ID = ROWNUM;
6 commit;
7 end ;
8
9 执行多条插入语句

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形式。

 1 /* 创建 */
 2 CREATE OR REPLACE PROCEDURE test1(v1 VARCHAR, v2 OUT INT) IS
 3 BEGIN
 4   SELECT COUNT(*) INTO v2 FROM user WHERE name = v1;
 5   Dbms_output.Put_line(v2);
 6 EXCEPTION
 7   WHEN NO_DATA_FOUND THEN
 8     v2 := 0;
 9     Dbms_output.Put_line(v2);
10   WHEN OTHERS THEN
11     ROLLBACK;
12 END;
13
14
15 /* 调用 */
16 DECLARE v1 VARCHAR(100);
17 v2 INT;
18 BEGIN
19   v1:=‘zhangsan‘;
20 test1(v1, v2);
21 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);

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

1 DECLARE
2 va hr_user.oa_name%TYPE;
3 ve INT;
4 BEGIN
5   va:=‘zhangsan‘;
6 test1(v1 =>va, v2 =>ve);
7 END;

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

 1 CREATE OR REPLACE PROCEDURE test1(v1 VARCHAR, v2 OUT INT) IS
 2 BEGIN
 3   SELECT COUNT(*) INTO v2 FROM user WHERE name = v1;
 4   Dbms_output.Put_line(v2);
 5   IF v2 > 1 THEN
 6     RAISE TOO_MANY_ROWS;
 7   ELSIF v2 = 0 THEN
 8     RAISE NO_DATA_FOUND;
 9   END IF;
10 EXCEPTION
11   WHEN NO_DATA_FOUND THEN
12     v2 := 0;
13     Dbms_output.Put_line(‘未查询到任何数据‘);
14   WHEN TOO_MANY_ROWS THEN
15     Dbms_output.Put_line(‘返回多行数据‘);
16   WHEN OTHERS THEN
17     ROLLBACK;
18 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;

 1 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
 2   v_count INT := 30;
 3   v_icre  INT DEFAULT v_increment;
 4 BEGIN
 5   WHILE v_icre < v_count LOOP
 6     BEGIN  --可加可不加
 7       Dbms_output.Put_line(‘打印内容:‘ || v_icre);
 8       v_icre := v_icre + 1;
 9     END;
10   END LOOP;
11 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;

 1 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
 2   v_name VARCHAR(100);
 3   v_type VARCHAR(100);
 4   CURSOR cur IS
 5     SELECT * FROM user WHERE rownum < 50;
 6 BEGIN
 7   FOR cur_result IN cur LOOP
 8     v_name := cur_result.name;
 9     v_type := cur_result.type;
10     Dbms_output.Put_line(‘打印内容:‘ || v_name || ‘   ‘ || v_type);
11   END LOOP;
12 END TEST1;

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

 1 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
 2   v_name VARCHAR(100);
 3   v_type VARCHAR(100);
 4   CURSOR cur IS
 5     SELECT name, type FROM user WHERE rownum < 50;
 6 BEGIN
 7   OPEN cur;
 8   LOOP
 9     FETCH cur
10       INTO v_name, v_type;
11     EXIT WHEN cur%NOTFOUND;
12     BEGIN
13       Dbms_output.Put_line(‘打印内容:‘ || v_name || ‘   ‘ || v_type);
14     END;
15   END LOOP;
16   CLOSE cur;
17 END TEST1;

使用3(while):

 1 CREATE OR REPLACE PROCEDURE TEST1(v_increment IN INT) IS
 2   v_name VARCHAR(100);
 3   v_type VARCHAR(100);
 4   CURSOR cur IS
 5     SELECT name, type FROM user WHERE rownum < 50;
 6   v_row cur%ROWTYPE;  --变量定义必须在begin之前
 7 BEGIN
 8   OPEN cur;
 9   FETCH cur INTO v_row; --fetch将值赋予v_row
10   WHILE cur%FOUND LOOP
11     Dbms_output.Put_line(‘打印内容:‘ || v_row.name || ‘   ‘ ||
12                          v_row.type);
13     FETCH cur INTO v_row;
14   END LOOP;
15   CLOSE cur;
16 END TEST1;

4.游标带参

 1 CREATE OR REPLACE PROCEDURE TEST1(v_oname IN VARCHAR) IS
 2   v_name VARCHAR(100);
 3   v_type VARCHAR(100);
 4   CURSOR cur(v_name1 VARCHAR) IS
 5     SELECT name, type FROM user
 6      WHERE name = v_name1
 7        AND rownum < 50;
 8   v_row cur%ROWTYPE;
 9 BEGIN
10   OPEN cur(v_oname);
11   FETCH cur
12     INTO v_row;
13   WHILE cur%FOUND LOOP
14     Dbms_output.Put_line(‘打印内容:‘ || v_row.name || ‘   ‘ ||
15                          v_row.type);
16     FETCH cur
17       INTO v_row;
18   END LOOP;
19   CLOSE cur;
20 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];

 1 CREATE OR REPLACE PROCEDURE TEST1(v_oname IN VARCHAR) IS
 2   v_name VARCHAR(100);
 3   v_type VARCHAR(100);
 4   CURSOR cur IS
 5     SELECT *
 6       FROM user
 7      WHERE name LIKE ‘%‘ || v_oname || ‘%‘
 8        AND rownum < 50;
 9   v_row cur%ROWTYPE;
10
11   TYPE type_user IS TABLE OF user%ROWTYPE INDEX BY BINARY_INTEGER;
12   user_table type_user;
13 BEGIN
14   OPEN cur;
15   FETCH cur BULK COLLECT
16     INTO user_table limit 5;
17   CLOSE cur;
18   FOR i IN 1 .. user_table.count LOOP
19     Dbms_output.Put_line(‘打印内容:‘ || user_table(i).name || ‘   ‘ || user_table(i) .type);
20   END LOOP;
21 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)

时间: 2024-10-06 09:18:54

Procedure-Function oracle的相关文章

MySQL:procedure, function, cursor,handler

Procedure & Function Procedure 语法: CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ([proc_parameter[,...]]) [characteristic ...] routine_body proc_parameter: [ IN | OUT | INOUT ] param_name type type: Any valid MySQL data type characteri

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

开发过程中,需要不停的备份数据库对象, 特别是存储过程, 每次手动备份不免很低能啊 历经几次修改终于, 完美了,O(∩_∩)O哈哈~      (当然,你也可以再改简便一点~~~) select dbms_metadata.get_ddl('PROCEDURE',"PROCEDURE_NAME",'NAG') 遇到大存储过程老是丢东西不说, 对象名 还老是 "用户名"."对象名" 的格式,腻烦人!~ CREATE OR REPLACE PROCE

Oracle procedure/function

--函数的创建 create function func1(dno number) return NUMBER--必须带有返回值 is v_max number;--定义返回值 begin select max(sal) into v_max--赋值 from emp where deptno= dno; RETURN v_max;--返回 end; --函数的调用,只能是表达式的一部分,不能单独调用 select * from emp where sal= func1(10); -------

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 contained inside a class. its scope is limited to that class, and cannot affect variables outside that class, even global variables. if you need to affec

Oracle procedure 基本语法

转自:http://lorry1113.javaeye.com/blog/513851 关键字: oracle 存储过程 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程名字 (     参数1 IN NUMBER,     参数2 IN NUMBER ) IS 变量1 INTEGER :=0; 变量2 DATE; BEGIN END 存储过程名字 2.SELECT INTO STATEMENT   将select查询的结果存入到变量中,可以同时将多个列存储多个变量

(转载)Oracle procedure 基本语法

转自:http://www.cnblogs.com/wolfplan/p/4004624.html 关键字: oracle 存储过程 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程名字 (     参数1 IN NUMBER,     参数2 IN NUMBER ) IS 变量1 INTEGER :=0; 变量2 DATE; BEGIN END 存储过程名字 2.SELECT INTO STATEMENT   将select查询的结果存入到变量中,可以同时将多个列

用sql语句导出oracle中的存储过程和函数

用sql语句导出oracle中的存储过程和函数: SET echo off ; SET heading off ; SET feedback off ; SPOOL 'C:/PRC.SQL' replace SELECT CASE WHEN LINE = 1 THEN 'CREATE OR REPLACE ' || TEXT WHEN LINE = MAX_LINE THEN TEXT || CHR(10 ) || '/' ELSE TEXT END FROM USER_SOURCE A LEF

oracle中delete drop truncate的用法和区别

数据库的运维中,经常会遇到delete drop truncate的操作,那么如何去把握它们的用法和区别呢? 比如当数据库空间爆满,已经增长到存储空间单个存储文件的最大值32G.你需要通过一些办法释放掉表空间或者扩容表空间来解决问题. 一般当系统中大量使用分区表,而针对分区表清除数据,是不会释放表空间的,必须把分区drop掉,才会释放空间. 下面我们具体了解一下这三个命令: 一.delete 1.delete是DML,执行delete操作时,每次从表中删除一行,并且同时将该行的的删除操作记录在r

Oracle基础(四)pl/sql

PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL).PL/SQL是Oracle数据库对SQL语句的扩展.在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断.循环等操作实现复杂的功能或者计算的程序语言. 总结下来就是是sql语言的扩展,sql语句+ 变量和常量+条件语句+循环语句+例外处理各种错误! PL/SQL的作用 使用PL/SQL可以编写具有很多高级功能的程

[Oracle系列整理04] oracle pl/sql 基础

PL/SQL块中只能直接嵌入SELECT,DML(INSERT,UPDATE,DELETE)以及事务控制语句 (COMMIT,ROLLBACK,SAVEPOINT),而不能直接嵌入DDL语句(CREATE,ALTER,DROP)和DCL语句 (GRANT,REVOKE) 1.检索单行数据    1.1使用标量变量接受数据  v_ename emp.ename%type;  v_sal   emp.sal%type;  select ename,sal into v_ename,v_sal fro