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 存储过程 ...
随机推荐
- 使用ioctl获取网卡统计信息
ethtool -S获取接口统计信息总共分三步: 1.获取统计项个数,使用SIOCETHTOOL+ETHTOOL_GSSET_INFO 2.(可选)获取统计项名字,使用SIOCETHTOOL+ETHT ...
- bat删除系统默认共享
在我们的系统中,有很多默认的共享是开启的,可以设置一个bat文件在每次开机的时候把共享删除. net share c$ /del net share d$ /del net share e$ /del ...
- Java中File常用的方法汇总
创建:createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false.mkdir() 在指定位置创建一个单级文件夹.mkdirs() 在指定位置创建 ...
- C语言面试题3
编程题 1.读文件file1.txt的内容(例如): 123456 输出到file2.txt: 563412 #include <stdio.h> #include <stdlib. ...
- 安装EKL
elasticsearch rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch /etc/yum.repos.d/ela ...
- jmeter自动生成报告
从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告. 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmete ...
- Qt下 QString转char*(转)
Qt下面,字符串都用QString,确实给开发者提供了方便,想想VC里面定义的各种变量类型,而且函数参数类型五花八门,经常需要今年新那个类型转换 Qt再使用第三方开源库时,由于库的类型基本上都是标准的 ...
- 洛谷 3784(bzoj 4913) [SDOI2017]遗忘的集合——多项式求ln+MTT
题目:https://www.luogu.org/problemnew/show/P3784 https://www.lydsy.com/JudgeOnline/problem.php?id=4913 ...
- Windows下 YOLOv3配置教程(YOLOv3项VS2013平台迁移的方法)
https://blog.csdn.net/maweifei/article/details/81150489
- Hibernate对substring和cast的支持问题
http://blog.sina.com.cn/s/blog_8acd9e4b0102uwev.html Hibernate对substring和cast的支持问题 问题:要比较日期的范围...这是只 ...