博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle存储过程基础语法总结
阅读量:3962 次
发布时间:2019-05-24

本文共 4556 字,大约阅读时间需要 15 分钟。

Oracle存储过程基础语法总结

1、基础概念

(1)什么是存储过程?

百度百科的解释:存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

笔者认为,存储过程类似于java或其他语言中的函数,都是将一些常用的复杂的业务逻辑过程或语句封装起来,通过简单的调用或传参调用,得到想要的结果。而数据库中的存储过程,即SQL语句和控制语句、系统函数等的结合,有很强大的功能。

(2)存储过程的使用方式?

存储过程编写完成后,可以通过SQLPLUS 、Oracle开发工具或第三方开发工具来调用运行。Oracle 使用CALL 语句来实现对存储过程的调用。

(3)Oracle存储过程的种类?

Oracle的存储过程支持传入参数和返回参数,按此种分类方式可以分为4类:

有传入参数,有返回参数
有传入参数,无返回参数
无传入参数,有返回参数
无传入参数,无返回参数

按照创建用户和权限,可以分为以下几类:

系统存储过程
系统预设的存储过程,用于实现以下常用的特定的功能。
本地存储过程
一般说的存储过程,指的就是本地存储过程。一般由用户编写,按照业务逻辑编写、封装,提供使用。
临时存储过程
一是本地临时存储过程,以“#”作为其名称的开头部分,存放在tempdb数据库,只有创建的用户可以调用它。
二是全局临时存储过程,以“##”作为其名称的开头部分,存放在tempdb数据库,所有连接上服务器的用户,都可以调用它。

(4)存储过程的优缺点?

优点:

–> 存储过程只有在创建时需要编译,使用时,不需要再进行编译,相比于SQL来说,执行速度更快,资源消耗更少。
–> 不需要重复编写复杂的代码,减少工作量。
–> 存储过程位于服务器上,每次调用时,只需要传存储过程名和参数,减少网络带宽资源消耗。
–> 存储过程中可以使用控制语句,可以完成SQL难以完成甚至无法完成的工作。
缺点:
–> 存储过程编写和调试时较为麻烦。
–> 当数据库进行迁移时,存储过程的迁移和维护工作量较大。

2、存储过程的编写

(1)基本语法

CREATE OR REPLACE PROCEDURE P_NAME[( 变量名 IN 变量类型,变量名 OUT 变量类型)] AS/IS	#变量声明	BEGIN	#业务逻辑、SQL语句	END [P_NAME];

实例

create or replace procedure get_student_name(student_id   in student.stu_id%TYPE,                                             student_name out student.stu_name%TYPE) isbegin  select stu_name into student_name from student where stu_id = student_id;  DBMS_OUTPUT.put_line('compete!');end get_student_name;

存储过程的执行

declarestudent_id student.stu_id%TYPE := 2020050801;student_name student.stu_name%TYPE;beginGET_STUDENT_NAME(student_id,student_name);DBMS_OUTPUT.put_line('学生名称:'||student_name);end;

输出结果

compete!学生名称:zhangsan

终端中可以使用“exec 存储过程名”执行。

(2) 变量

变量类型

固定类型

如NUMBER、VARCHAR2、DATE等
引用类型
%TYPE #普通变量
声明方式:username tbname.username%TYPE
因为数据库的数据类型往往可能和预设类型不一致(例如:名称声明为varchar2(20),但是实际名称可能会超过20),所以一般建议使用引用型变量,及时数据库对字段进行了修改,也不会影响存储过程的使用,使程序更具健壮性。
%ROWTYPE #记录型变量
声明方式
rowtb = tbname%ROWTYPE
如果需要使用的字段较多,每一个字段都去声明的话,会非常麻烦,一般可以使用记录型变量,使用时类似于对象使用的方式:rowtb.colname
如果使用的字段较少的情况下,一般不建议使用记录型变量,变量存储的内容更多,会造成系统资源的浪费。
一个记录型变量一次只能存储一行数据,且必须是一条数据,超出或字段缺少都会报错。

实例

declarestudent_msg student%ROWTYPE;beginselect * into student_msg from student where stu_id='2020050801';DBMS_OUTPUT.put_line('学生名称是:'||student_msg.stu_name||'分数是:'||student_msg.score);end;

输出结果

学生名称是:zhangsan分数是:100

声明方式

变量名 变量类型(变量长度)
例如:username varchar2(30) ;

赋值方式

第一种:
直接赋值: :=
如:username varchar2(30) := ‘张三’;
第二种:
语句赋值: select 值 into 变量
如:select ‘张三’ into username from dual;

(3)控制语句

打印输出信息

DBMS_OUTPUT.PUT_LINE('HELLO WORLD');

选择控制语句

IF 条件 		THEN 执行语句	ELSIF 条件 		THEN 执行语句	ELSE	 	执行语句	END IF

注意:ELSIF的写法

实例

declare  row_count number(10);begin  select count(1) into row_count from student;  dbms_output.put_line('数据笔数为:' || row_count);  if row_count >= 1 and row_count <= 3     then      dbms_output.put_line('数据笔数在1~3之间为:' || row_count);  elsif row_count >= 4 and row_count <= 6     then      dbms_output.put_line('数据笔数在4~6之间为:' || row_count);  else      dbms_output.put_line('数据笔数大于6笔,为:' || row_count);  end if;end;

循环控制语句

LOOP循环

LOOPWHEN 条件 EXIT执行语句END LOOP

实例

打印 1-5

declare  num number := 0;begin  loop    num := num + 1;        DBMS_OUTPUT.put_line(num);        exit when num>=5;          end loop;end;

输出结果

12345

WHILE循环

WHILE 条件 LOOP执行语句END LOOP;

实例

declare  num number := 0;begin while num<5 loop   num := num + 1;   dbms_output.put_line(num);   end loop;end;
FOR 值 IN 列表 LOOP执行语句END LOOP;

实例

begin  for stu in (select * from student)    loop      dbms_output.put_line(stu.stu_id);          end loop;end;

输出结果

2020050801202005080220200508032020050804

(4)游标

什么是游标?

游标是用于存储一个查询返回的多行数据,通过遍历游标,可以逐行访问处理该结果集的数据。

语法

游标声明

CURSOR 游标名[(参数列表)] IS 查询语句;

游标的打开

OPEN 游标名;

游标的取值

FETCH 游标名 INTO 变量列表;

游标的关闭

CLOSE 游标名;

属性

游标的属性 返回值类型 说明
%ROWCOUNT 整型 获得FETCH语句返回的数据行数
%FOUND 布尔型 最近的FETCH语句返回一行数据为真,否则为假
%NOTFOUND 布尔型 与%FOUND属性返回值相反
%ISOPEN 布尔型 游标已经打开值为真,否则为假

其中,%NOTFOUND在游标中找不到元素的时候返回TRUE,通常用来判断退出循环。默认值为FALSE

实例

declare  cursor curs is    select stu_id, stu_name, score from student;  student_id    student.stu_id%TYPE;  student_name  student.stu_name%TYPE;  student_score student.score%TYPE;begin  open curs;  loop    exit when curs%NOTFOUND;    fetch curs      into student_id, student_name, student_score;      dbms_output.put_line('学号:' || student_id || ',学生姓名:' || student_name ||                         ',学生分数:' || student_score);  end loop;  close curs;end;

输出结果

学号:2020050801,学生姓名:zhangsan,学生分数:100学号:2020050802,学生姓名:lisi,学生分数:90学号:2020050803,学生姓名:wangwu,学生分数:98.5学号:2020050804,学生姓名:zhaoliu,学生分数:92.6学号:2020050804,学生姓名:zhaoliu,学生分数:92.6

好了,Oracle的存储过程基本用法已经介绍完了,实用性还是非常强的,后续工作和实际使用过程中会复杂的多,但是基础掌握很重要。但是实际工作中,操作数据库还是尽量减少存储过程的使用,毕竟SQL才是查询数据库的主要方式。

转载地址:http://drezi.baihongyu.com/

你可能感兴趣的文章
Spring核心ioc
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
Struts2+Spring3+Mybatis3开发环境搭建
查看>>
mongoDB入门必读(概念与实战并重)
查看>>
通俗易懂解剖jbpm4
查看>>
rsync
查看>>
makefile
查看>>
linux 文件权限
查看>>
一些比较好的golang安全项目
查看>>
HTTP状态码
查看>>
go语言
查看>>
mysql mariaDB 以及存储引擎
查看>>
游戏行业了解介绍
查看>>
linux at 命令使用
查看>>
Go在windows下执行命令行指令
查看>>
inotify
查看>>
inode
查看>>
Shell: sh,bash,csh,tcsh等shell的区别
查看>>
golang ubuntu 配置 笔记
查看>>
vim 常用命令
查看>>