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;
存储过程创建语法: 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的更多相关文章
- MySQL:procedure, function, cursor,handler
Procedure & Function Procedure 语法: CREATE [DEFINER = { user | CURRENT_USER }] PROCEDURE sp_name ...
- oracle 备份数据库对象(存储过程PROCEDURE,FUNCTION,VIEW,TRIGGER...)
开发过程中,需要不停的备份数据库对象, 特别是存储过程, 每次手动备份不免很低能啊 历经几次修改终于, 完美了,O(∩_∩)O哈哈~ (当然,你也可以再改简便一点~~~) select db ...
- [转]Easy Stored Procedure Output Oracle Select
本文转自:http://www.oraclealchemist.com/oracle/easy-stored-procedure-output/ I answered a question on a ...
- 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 ...
- [转]MONTHS_BETWEEN Function - Oracle to SQL Server Migration
本文转自:http://www.sqlines.com/oracle-to-sql-server/months_between In Oracle, MONTHS_BETWEEN(date1, dat ...
- 通过PLSQL创建Database link,DBMS_Job,Procedure,实现Oracle跨库传输数据
前一阵领导安排了一个任务:定时将集团数据库某表的数据同步至我们公司服务器的数据库,感觉比写增删改查SQL有趣,特意记录下来,希望能帮到有类似需求的小伙伴,如有错误也希望各位不吝指教 环境描述: 集团数 ...
- 存储过程和函数 PROCEDURE & FUNCTION
SQL语句执行的时候,要首先编译,然后在被执行.在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行. 具体而言 ...
- 修改Mysql procedure,function and view definer
1 一次性修改遇到错误 update mysql.proc set definer='root@%'; update mysql.proc set definer='root@%'; ERROR 10 ...
- 移植Oracle procedure 到 postgresql
1.登录postgresql psql -h 192.168.137.131 -p 5432 postgres satusc@6789#JKL 2.创建用户 CREATE USER name thun ...
- Oracle procedure 基本语法
转自:http://lorry1113.javaeye.com/blog/513851 关键字: oracle 存储过程 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程 ...
随机推荐
- Json.NET Updates: Merge, Dependency Injection, F# and JSONPath Support
Json.NET 6.0 received 4 releases this year, the latest last week. Over these releases, several new f ...
- Tensorflow & Python3 做神经网络(视频教程)
Tensorflow 简介 1.1 科普: 人工神经网络 VS 生物神经网络 1.2 什么是神经网络 (Neural Network) 1.3 神经网络 梯度下降 1.4 科普: 神经网络的黑盒不黑 ...
- JVM(上)
堆.栈 JVM内存≍Heap(堆内存)+PermGen(方法区)+Thrend(栈)Heap(堆内存)=Young(年轻代)+Old(老年代),官方文档建议整个年轻代占整个堆内存的3/8,老年代占整个 ...
- Why my setting does not work?
lab mypc server7000 -> 5900 1080 -> 10800 10800 -> inter ...
- UOJ 393 【NOI2018】归程——可持久化并查集
题目:http://uoj.ac/problem/393 题解:https://www.cnblogs.com/HocRiser/p/9368067.html 但过不了 UOJ 的 hack 数据.不 ...
- WPF中控制窗口显示位置的三种方式
首先新建一个WPF工程,在主界面添加一个按钮,并给按钮添加点击事件button1_Click,然后新建一个用于测试弹出位置的窗口TestWindow.1.在屏幕中间显示,设置window.Window ...
- PHP中imagecopyresampled参数详解
原文链接http://blog.csdn.net/ajaxchen_615/article/details/5941181 做php缩微图程序,用到了imagecopyresampled函数,在网上找 ...
- busybox下的tftp client
# tftp -p -l file host # put local file to remote host # tftp -g -r file host # get remote fil ...
- vscode中使用Experimental Decorators报错
在vscode中使用es7的新语法decorator会报错,如图: 这是错误来自与vscode的JS support,只要在项目根目录下创建一个jsconfig.json文件,添加如下内容: { &q ...
- R语言学习——R读取txt、csv、xls和xlsx格式文件
最近项目中运用到了R读取文件数据,所以把相关好用的.经过验证的方法总结了一下,有效避免下次入坑. 1. R读取txt文件 使用R读取txt文件直接使用read.table()方法进行读取即可,不需要加 ...