转自:http://blog.sina.com.cn/s/blog_4c302f060101i4o1.html

一 PL/SQL的介绍
1 PL/SQL是什么?
PL/SQL(procedural language/SQL)是Oracle在标准的sql语言上的扩展。pl/sql不仅允许嵌入sql语言,还可以定义变量和常量,允许使用条件语句和循环语句,允许使用例外处理各种错误,这样使得它的功能变的更加强大。
(1)过程,函数,触发器是PL/SQL编写的
(2)过程,函数,触发器是在Oracle中的
(3)PL/SQL是非常强大的数据库过程化语言
(4)过程,函数可以在java程序中调用
2 学习的必要性
(1)提供应用程序的运行性能
传统的操作数据库的方法是:sql语句写到java程序中,java连接Oracle,传递给数据库,Oracle翻译SQL语句,编译成自己能识别的代码,然后才执行。
PL/SQL:直接在Oracle中写过程,由java调用过程,而此过程已经编译成可执行代码。这样节省了时间。
(2)模块化的设计思想[分页的过程,订单的过程,转账的过程。。。]
(3)减少网络传输量
传统的方法:数据库和java中的SQL语句不在同一机器上,要经过网络传输
过程:直接调用
(4)提高安全性
过程中封装了用户名、密码、表名、字段名等信息。
3 pl/sql的缺点
移植性不好  换数据库了就不能用了
4 pl/sql开发工具
(1)sqlplus开发工具  开始——运行——sqlplusw——用户名、口令
(2)pl/sql developer 开发工具  文件——新建命令窗口
5 例子:
eg1:编写一个存储过程,该过程可以向某表中添加记录——用sqlplus开发工具
(1)创建一张简单表 :create table mytest(name varchar2(30),passwd varchar2(30));
(2)创建过程:
create or replace procedure sp_pro1 is --replace:代表如果原来有sp_pro1将被替换
begin--执行部分
insert into mytest values('李叶','m123');
end;
回车 / 回车
(3)如何查看错误信息
如果编译有错,则可以用show error显示错误。如果没错,则提示过程已创建。
(4)如何调用该过程
①第一种方式:exec 过程名(参数值1,参数值2。。。);
②第二种方式:call 过程名(参数值1,参数值2。。。);
eg2:编写一个存储过程,该过程可以删除某表记录——用pl/sql developer开发工具
create or replace procedure sp_pro2 is 
begin
delete from mytest where name='韩顺平';
end;
/
exec sp_pro2;
 
二 PL/SQL的基础
    开发人员使用pl/sql编写应用程序模块时,不仅需要掌握sql语句的编写方法,还要掌握pl/sql语句及语法规则。pl/sql编程可以使用变量和逻辑控制语句,从而可以编写非常有用的功能模块。比如:分页存储过程模块、订单处理存储过程模块、转账存储过程模块。。而且如果使用pl/sql编程,我们可以轻松地完成非常复杂的查询要求。
1 pl/sql可以做什么?
(1)简单分类
块(编程的基础单元) 过程(存储过程)、函数、触发器和包
(2)编写规范
①注释
单行注释 --
多行注释
②表示符号的命名规范
1)当定义变量时,建议用v_作为前缀v_sal
2)当定义常量时,建议用c_作为前缀c_rate
3)当定义游标时,建议用_cursor作为后缀emp_cursor
4)当定义例外时,建议用e_作为前缀e_error
2 pl/sql块介绍
(1)介绍
    块(block)是pl/sql的基本程序单元,编写pl/sql程序实际上就是编写pl/sql块。要完成相对简单的应用功能,可能只需要编写一个pl/sql块;但是如果要想完成复杂的功能,可能需要在一个pl/sql块中嵌套其它的pl/sql块。
(2)块结构示意图
pl/sql块由三个部分构成:定义部分、执行部分、例外处理部分。
declare
begin
exception
end;
块结构和java程序的比较
java程序结构:
public static void main(String[] args)
{
int a=1;//定义部分
try{
a++;//执行部分
}
catch(Exception e){
//捕获异常
}
}
 
3 例子 
eg1 只包括执行部分的pl/sql块
set serveroutput on --打开输出选项
begin
    dbms_output.put_line('hello');
end;
相关说明:dbms_output是Oracle所提供的包(类似java的开发包),该包包含一些过程,put_line就是dbms_output包的一个过程。
 
eg2  包括定义部分和执行部分
declare
    v_ename varchar2(5); --定义字符串变量
    v_sal number(7,2);
begin
    select ename,sal into v_ename,v_sal from emp where empno=&no;
    dbms_output.put_line('雇员名:'||v_ename||' 工资:'||v_sal);
end;
相关说明:(1) select ename into v_ename from... 把查出的ename赋值给v_ename
 (2)& 表示要接收从控制台输入的变量
 (3)|| 字符串连接符
 
eg3 包含定义部分、执行部分和例外处理部分
    为了避免pl/sql程序的运行错误,提高pl/sql的健壮性,应该对可能的错误进行处理,这个很有必要:
① 比如在eg2中,如果输入了不存在的雇员号,应当做例外处理
②有时出现异常,希望用另外的逻辑处理
相关说明:Oracle事先预定义了一些例外,no_data_found就是找不到数据的例外。
declare
    v_ename varchar2(5);--定义字符串变量
    v_sal number(7,2);
begin
    select ename,sal into v_ename,v_sal from emp where empno=&no;
    dbms_output.put_line('雇员名:'||v_ename||' 工资:'||v_sal);
--异常处理
exception
when no_data_found then 
dbms_output.put_line('朋友你的编号输入有误!');
end;
 
4 过程
    过程用于执行特定的操作,当建立过程时,既可以指定输入参数(in),也可以指定输出参数(out),通过在过程中使用输入参数,可以将数据传递到执行部分;通过使用输出参数,可以将执行部分的数据传递到应用环境。在sqlplus中可以使用create procedure命令来建立过程。
 
5 实例
①请考虑编写一个过程,可以输入雇员名,新工资 可修改雇员的工资
create procedure sp_prop3(sp_Name varhcar2,newSal number) is
begin
--执行部分 根据用户名修改工资
update emp set sal=newSal where ename=sp_Name;
end;
② 如何调用过程有两种方法
exec sp_pro3('SCOTT',4768);
或者call。。。
③ 如何在java中调用一个存储过程,C C++程序都可以调用
启动eclipse——file new java project——project命名——new package 命名 com.sp——new class 命名 TestOraclePro
package com.sp;
import java.sql.*;
public class TestOraclePro{
public static void main(String[] args)
{
try{
//1.加载驱动
Class.forName("Oracle.jdbc.driver.OracleDriver");
//2. 得到连接
Connection ct=DriverManager.getConnection("jdbc:Oracle:thin:@127.0.0.1","SCOTT","m123");
//3 创建CallableStatement 
CallableStatement cs=ct.prepareCall("{call sp_pro3(?,?)}");
//4 给?赋值
cs.setString(1,"SMITH");
cs.setInt(2,10);
//5 执行
cs.execute();
//关闭
cs.close();
ct.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
 
加入驱动 引入一个jar包  property——jave build path——libraries——add external jars
问题:如何使用过程返回值??
 
6 函数
函数用于返回特定的数据,当建立函数时,在函数的头部必须包含return子句,而在函数体内必须包含return语句返回的数据。我们可以使用create function来建立函数,
实例:
--输入雇员的姓名,返回该雇员的年薪
create function sp_fun2(spName varchar2) return number is yearSal number(7,2);
begin
--执行部分
select sal*12+nvl(comm,0)*12 into yearSal from emp where ename=spName;
return yearSal;
end;
调用
var abc number;
call sp_fun2('SCOTT') into:abc;
 
7 包
包用于逻辑上组合过程和函数,它是由包规范和包体组成。
① 我们可以使用create package命令来创建包:
实例
--创建一个包sp_package
--声明该包有一个过程
--声明该包有一个函数
create package sp_package is
    procedure update_sal(name varchar2,newsal number);
    function annual_income(name varchar2) return number;
end;
/ 执行 --包被创建
包的规范只包含了过程和函数的声明,但是没有过程和函数的实现代码。包体用于实现包规范中的过程和函数。
② 建立包体可以使用create package body命令
 
--给包 sp_package 实现包体
create or replace package body sp_package is
procedure update_sal(name varchar2,newsal number) is
begin
undate emp set sal=newsal where ename=name;
end;
function annual_income(name varchar2) return number is annual_sal number;
begin 
select sal*12+nvl(comm,0)*12 into annual_sal from emp where ename=name;
return annual_sal;
end; 
end;
/ 包体被创建 
③ 如何调用包的过程或函数
当调用包的过程或是函数时,在过程和函数前需要带有包名,如果要访问其它方案的包,还需要在包名前加方案名
如:call sp_package.update_sal('SCOTT',1500);
 
8 触发器
触发器是指隐含的执行的存储过程。当定义触发器时,必须要指定触发的事件和触发的操作,常用的触发事件包括insert,update,delete语句,而触发操作实际就是一个pl/sql块。可以使用create trigger来建立触发器。
 
9 定义并使用变量
在编写pl/sql程序时,可以定义变量和常量;在pl/sql程序中包括:
①标量类型(scalar)
②复合类型(composite)
③参照类型(reference)
④lob(large Object)
(1)标量(scalar)——常用类型
在编写pl/sql块时,如果要使用变量,需在定义部分定义变量。
pl/sql中定义变量和常量的语法如下:
identifier [constant] datatype [not null] [:=|default expr]
identifier:名称
constant:指定常量。需要指定它的初始值,且其值是不能改变的
datatype:数据类型
not null:指定变量值不能为null
:= 给变量或是常量指定初始值
default: 用于指定初始值
expr:指定初始值的pl/sql表达式,可以是文本值、其它变量、函数等
例子:
①定义一个变长字符串
v_ename varchar2(10);
②定义一个小数 范围-9999.99~9999.99
v_sal number(6,2);
③定义一个小数并给一个初始值5.4
v_sal2 number(6,2):=5.4
④定义一个日期类型的数据
v_hiredate date;
⑤定义一个布尔变量,不能为空,初始值为false
v_valid boolean not null default false;
 
使用标量
    在定义好标量之后,就可以使用这些变量。这里需要说明的是pl/sql块为变量赋值不同于其它的编程语言,需要在等号前加冒号(:=)
例子
下面以输入员工号,显示员工姓名、工资、个人所得税(税率为0.03)为例,说明变量的使用,看看如何编写。
declare
c_taxrate constant number(3,2):=0.03;
v_name varchar2(5);
v_sal number(7,2);
v_tax_sal number(7,2)
begin
select ename,sal into v_name,v_sal from emp where empno=&no;
--计算所得税
v_tax_sal:=sal*c_taxrate;
--输出
dbms_optput.put_line('姓名是:'||v_name||'工资:'||v_sal||'交税:'||v_tax_sal);
(2)标量(scalar)——使用%type类型
对于上面的pl/sql块有一个问题:
就是如果员工的姓名超过了5个字符的话,就会有错误,为了降低pl/sql程序的维护工作量,可以使用%type属性定义变量,这样它就会按照数据库列来确定你定义的变量的类型和长度。
标识符名 表名.列名%type;   v_name emp.ename%type;  v_name的类型和emp.ename的类型长度一致
(3)复合变量(composite)——介绍
①pl/sql记录
    类似于高级语言中的结构体,需要注意的是当引用pl/sql记录成员时,必须要加记录变量作为前缀(记录变量.记录成员)如下:
declare
--定义一个pl/sql记录类型,名字emp_record_type,类型包含3个数据分别是name,salary,title。
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type,
title emp.job%type
);
--定义了一个变量,该变量的类型是emp_record_type
sp_record emp_record_type;
begin
select ename,sal,job into sp_record from emp where empno=7788;
dbms_output.put_line('员工名:'||sp_record.name||'工资是:'||sp_record.salary);
 
②pl/sql表
   相当于高级语言中的数组,但是需要注意的是在高级语言中数组的下表不能为负数,而pl/sql是可以为负数的,并且表元素的下表没有限制。实例如下
declare
--定义了一个pl/sql表类型,sp_table_type,该类型用于存放emp.ename%type
type sp_table_type is table of emp.ename%type
index by binary_integer;--下表为整数,可以为负
sp_table sp_table_type;--定义了一个sp_table_type类型的变量sp_table
begin  
select ename into sp_table(0) from emp where empno=7788;--如果把where去掉,则应该使用参照变量
dbms_output.put_line('员工名:'||sp_table(0)); 
end;
③嵌套表
④varray
 
(4)参照变量
    参照变量是指用于存放数值指针的变量,通过使用参照变量,可以使得应用程序共享相同对象,从而降低占用的空间。在编写pl/sql程序时,可以使用游标变量(ref cursor)和对象类型变量(ref obj_type)两种参照变量类型。
参照变量——ref cursor游标变量
使用游标时,当定义游标时不需要指定相应的select语句,但是当使用游标时(open时)需要指定select语句,这样一个游标就和一个select语句结合了。
实例:
①请使用pl/sql编写一个块,可以输入部门号,并显示该部门所有员工姓名和他的工资
declare
--定义游标类型
type sp_emp_cursor is ref cursor;
--定义一个游标变量
test_cursor sp_emp_cursor;
--定义两个变量
v_ename emp.name%type;
v_sal emp.sal%type;
--执行
begin
--把test_cursor和一个select结合
open test_cursor for select ename,sal from emp where deptno=&no ;
--循环取出
loop
fetch test_cursor into v_ename,v_sal;
--判断是否test_cursor为空
exit when test_cursor not found;
dbms_output.put_line('名字:'||v_ename||' 工资:'||v_sal);
end loop;
end;
②在①的基础上,如果某个员工的工资低于200元,就增加100元
type sp_emp_cursor is ref cursor;
--定义一个游标变量
test_cursor sp_emp_cursor;
--定义两个变量
v_ename emp.name%type;
v_sal emp.sal%type;
--执行
begin
--把test_cursor和一个select结合
open test_cursor for select ename,sal from emp where deptno=&no ;
--循环取出
loop
fetch test_cursor into v_ename,v_sal;
--判断工资是否小于200 决定是否更新
if v_sal<200 then
update emp set sal=sal+100 ;
--判断是否test_cursor为空
exit when test_cursor not found;
dbms_output.put_line('名字:'||v_ename||' 工资:'||v_sal);
end loop;
end;

oracle PL/SQL的介绍的更多相关文章

  1. ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍

    如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...

  2. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  3. [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  4. ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)

    原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!)   继上篇:ORACLE P ...

  5. [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

    原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...

  6. [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)

    原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...

  7. 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航

    原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...

  8. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  9. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...

随机推荐

  1. live555源码学习笔记之TaskScheduler

    今天抽空研究了下live555的任务实现: TaskScheduler分为三种任务:socket handler,event handler,delay task.这三种任务的特点是,前两个加入执行队 ...

  2. Service Mesh简介

    1.1 Service Mesh   1.1.1 什么是Service Mesh Service Mesh是最近才兴起的一个名词,最早在2016年9月29日由开发Linkerd的Buoyant公司首次 ...

  3. 微信小程序调用微信登陆获取openid及用户信息 java做为服务端

    转载的文章,很不错 https://blog.csdn.net/weilai_zhilu/article/details/77932630

  4. get和post的解析

    get 直接获取数据 post 将数据发送到服务端缓存下来,当无法缓存数据或用户输入未知字符时用post, get:常用于数据 post:不想缓存数据,不再浏览器中缓存数据,在服务端可以,因为取数据及 ...

  5. CentOS 7安装Oracle 11gR2以及设置自启动(1)

    一.环境准备 1.正确无误的CentOS 7系统环境 虚拟机要求: 内存至少2G 处理器至少2个 根分区要大于20G(安装oracle很占空间,空闲空间要足够) 2.正确的JDK环境 CentOS 7 ...

  6. android scrollview listview显示不全

    原来处理方法是重写ListView import android.content.Context; import android.util.AttributeSet; import android.v ...

  7. android-menudrawer 和SlidingMenu 用法

    项目地址: https://github.com/gokhanakkurt/android-menudrawer    https://github.com/jfeinstein10/SlidingM ...

  8. git遇到的问题之“Please make sure you have the correct access rights and the repository exists.”

    对于git的提交一直很小心翼翼,感觉一不小心就会踩到莫名的坑. 这不, 某天commit 就遇到了On branch master nothing to commit (working directo ...

  9. Hibernate的hql语句save,update方法不执行

    Hibernate的hql语句save,update方法不执行 可能出现的原因问题: 未进行事务管理 需要进行xml事务配置或者注解方式的事务配置

  10. Java - 24 Java 封装

    Java 封装 在面向对象程式设计方法中,封装(英语:Encapsulation)是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装可以被认为是一个保护屏障,防止该类的代码和数据被外 ...