语法
块定义语法
DECLARE
--定义部分--定义常量、变量、复杂数据类型、游标
BEGIN
--执行部分--PL/SQL语句和SQL语句
EXCEPTION
--异常处理部分——处理运行错误
异常中可以插入逻辑代码
END;
注:PL/SQL中结束输入使用‘/’字符
dbms_output是oracle提供的系统包;put_line是该包中的过程,用于输出字符串信息。当使用dbms_output包时必须要先激活服务器输出
dbms_output.put_line(“输出的字符串内容”);
激活服务器输出语句: set serveroutput on(默认是关闭的)
示例:
DECLARE
str varchar(5) --变量的定义
BEGIN
Select name INTO str FROM emp --INTO是将name的值赋值给str
where empno=$no; --$no是替代变量
EXCEPTION
When NO_DATA_FOUND then --PL/SQL预定义的异常类型
dbms_output.put_line(“输出的字符串内容”);
END;
NO_DATA_FOUND 只有在select..into中才可能出现,
变量定义语法
变量名 [CONSTANT] 数据类型 [NOT NULL] [:=|DEFAULT 默认值或函数]
--CONSTANT表示常量;
--:=设置默认值
%TYPE属性
示例:
Name emp.ename%TYPE --name与emp表中ename列的类型和长度相同
Sex Name%TYPE --sex与name类型和长度相同
%ROWTYPE属性
语法:
变量名 表名%ROWTYPE
示例:
Str T1%ROWTYPE
--str变量对应T1表中所有列,并且该表中的所有列的类型与长度相同
PL/SQL中使用的操作符
:= --赋值操作符
=> --关联操作符
|| --连接操作符
PL/SQL游标
游标定义语法:
CURSOR 游标名 IS SQL语句
游标名%ISOPEN 判断游标是否已经打开
游标名%FOUND SQL语句有作用行市,其属性值为TRUE;
游标名%NOTFOUND SQL语句没有作用行市,其属性值为TRUE;
游标名%ROWCOUNT 返回SQL语句所作用的总行数
注:游标名默认为‘SQL’
PL/SQL控制语句
1、分支语句
IF 条件 THEN 执行操作
ELSEIF 条件THEN 执行操作
ELSE 执行操作
END IF;
2、多重分支语句
CASE 表达式
WHEN 要判断的值 THEN 执行操作
WHEN 要判断的值 THEN 执行操作
ELSE 执行操作
END CASE;
3、循环语句一
WHILE 条件 LOOP
执行操作···
END LOOP;
4、循环语句二
FOR 变量 IN [REVERSE] 起点值 ..终点值 LOOP
执行操作
END LOOP;
注:REVERSE表示由终点值到起点值循环; ..是固定格式;
过程
调用过程有两种方法: exec call
exec是sqlplus的命令,只能在sqlplus中使用。call是sql命令,任何工具都可以使用。
create procedure sp_pro3(spName varchar2, newSal number) is
--不要写成number(3,2),表明类型就可以了,不需要大小。就好像Java写方法时的参数一样
begin
--执行部分,根据用户名去修改工资
update emp set sal=newSal where ename=spName;
end;
/
begin
--执行部分,根据用户名去修改工资
update emp set sal=newSal where ename=spName;
end;
说明:
不用 declare 语句
参数列表里的IN表示向存储过程传递参数,OUT表示从存储过程返回参数。而IN OUT 表示传递参数和返回参数;在声明变量的时候,IN变量不可以赋常量,OUT可以赋常量,不可以赋变量.
//演示java程序去调用oracle的存储过程案例
Java代码
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:[email protected]:1521:MYORA1","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();
}
}
}
函数
函数用于返回特定的数据,当建立函数时,在函数头部必须包含return子句。而在函数体内必须包含return语句返回的数据。我们可以使用create function来建立函数,实际案例:
--输入雇员的姓名,返回该雇员的年薪
create function annual_incomec(name varchar2)
return number is
annual_salazy number(7,2);
begin
--执行部分
select sal*12+nvl(comm, 0) into annual_salazy from emp where ename=name;
return annual_salazy;
end;
如果函数创建过程有编译错误,可以使用show error;命令显示错误.
函数与过程的区别
1.返回值的区别,函数有1个返回值,而存储过程是通过参数返回的,可以有多个或者没有
2.
函数和过程的主要区别不在于返回值,而在于他们的调用方式。函数可以在查询语句中直接调用,而存储过程必须单独调用.
函数一般情况下是用来计算并返回一个计算结果而存储过程一般是用来完成特定的数据操作(比如修改、插入数据库表或执行某些DDL语句等等)
包
包是一种将过程、函数和数据结构捆绑在一起的容器;包由两个部分组成:外部可视包规范,包括函数头,过程头,和外部可视数据结构;另一部分是包主体(package body),包主体包含了所有被捆绑的过程和函数的声明、执行、异常处理部分。
1、 包规范创建语法
create [or replace] package 程序包名
is | as
procedure 过程名(过程参数列表);
function 函数名(函数参数列表);
……
end 程序包名;
2、 包体创建语法
create [or replace] package body 程序包名
is | as
之前定义的函数、过程的具体实现部分
end 程序包名;
3、包的调用
当调用包的过程或是函数时,在过程和函数前需要带有包名,如果要访问其它方案的包,还需要在包名前加方案名。
exec 程序包名.过程名(参数列表);