简介:PL/SQL是是甲骨文公司开发,嵌入在Oracle数据库中的编程语言。
基础
- 块结构
- declare 声明部分 – 所有变量,游标,子程序,和其他元素
- begin - end ; – 程序主体,可执行命令
- 常见符号解释:
符号 | 含义 |
---|---|
|| | 字符串连接符 |
:+ | 赋值运算符 |
% | 获得相同的数据类型 |
= | 相等运算符 |
- 变量的常见类型:
类型 | 含义 |
---|---|
varchar2 | 可变长字符串 |
int | 整数类型 |
number (precision,scale) | precision表示数字中的有效位,如果没有指定precision的话,oracle将使用38作为精度, 如果scale大于零,表示数字精度到小数点右边的位数;scale默认设置为0;如果scale小于零,oracle将把该数字取舍到小数点左边的指定位数 |
clob | 用于存储字符大块数据在数据库中 大小为 8 - 128 TB |
date | 日期和时间 |
- 数组 TYPE varray_type_name IS VARRAY(n) OF element_type
DECLARE
type namesarray IS VARRAY(5) OF VARCHAR2(10);
type grades IS VARRAY(5) OF INTEGER;
names namesarray; --拿到数组的引用,下面就可以变长使用该数组
marks grades;
total integer;
BEGIN
names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz');
marks:= grades(98, 97, 78, 87, 92);
total := names.count; --求数组的长度
dbms_output.put_line('Total '|| total || ' Students');
FOR i in 1 .. total LOOP
dbms_output.put_line('Student: ' || names(i) || ' Marks: ' || marks(i));
END LOOP;
END;
- 全局变量与局部变量
DECLARE
-- Global variables
num1 number := 95;
BEGIN
DECLARE
-- Local variables
num1 number := 195;
BEGIN
END;
END;
- 常量
PI constant number := 3.14;
- SELECT INTO 取值出来使用: SELECT 表中变量 INTO 定义变量 FROM XXX
declare
c_id customers.id%type := 1;
c_name customers.name%type;
c_addr customers.address%type;
c_sal customers.salary%type;
begin
select name,address,salary into c_name,c_addr,c_sal from customers where id = c_id;
dbms_output.put_line('Customer '||c_name||' from '||c_addr||' earns '||c_sal);
end;
- 控制语句
- IF 语句:if 使用 end if 结束
DECLARE
a number(3) := 100;
BEGIN
IF ( a = 10 ) THEN
dbms_output.put_line('Value of a is 10' );
ELSIF ( a = 20 ) THEN
dbms_output.put_line('Value of a is 20' );
ELSE
dbms_output.put_line('None of the values is matching');
END IF;
dbms_output.put_line('Exact value of a is: '|| a );
END;
2. CASE语句: 以end case 结束
declare
grade char(1) := 'A';
begin
case grade
when 'A' then dbms_output.put_line('A');
when 'B' then dbms_output.put_line('B');
else dbms_output.put_line('NO');
end case;
end;
- 循环控制语句
1. LOOP :已END LOOP结束
DECLARE
x number := 10;
BEGIN
LOOP
dbms_output.put_line(x);
x := x + 10;
IF x > 50 THEN
exit;
END IF;
END LOOP;
-- after exit, control resumes here
dbms_output.put_line('After Exit x is: ' || x);
END;
2. WHILE: 已END LOOP结束
DECLARE
a number(2) := 10;
BEGIN
WHILE a < 20 LOOP
dbms_output.put_line('value of a: ' || a);
a := a + 1;
END LOOP;
END;
- FOR: 已END LOOP结束
DECLARE
a number(2);
BEGIN
FOR a in 10 .. 20 LOOP -- 10 .. 20 表示10-20 全包含
dbms_output.put_line('value of a: ' || a);
END LOOP;
END;
进阶 (进步进阶无所谓半小时就看完了)
- 两种子程序:
参数 in :入参, out : 返回值, in out :入参且是返回值
create PROCEDURE squareNum(x IN OUT number) IS
BEGIN
x := x * x;
END;
1. 函数:这些子程序返回一个值,主要用于计算并返回一个值。
1.1. 创建函数
CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])] RETURN return_datatype
{IS | AS}
BEGIN
< function_body >
RETURN XXX;
END [function_name];
- 过程:这些子程序没有直接返回值,主要用于执行操作。
2.1. 创建过程
Create PROCEDURE findMin(x IN number, y IN number, z OUT number) IS
BEGIN
IF x < y THEN
z:= x;
ELSE
z:= y;
END IF;
END;
2.2. 销毁过程
drop procedure procedure_name;
- 游标
- 隐式游标
DML操作和单行SELECT语句会使用隐式游标,它们是:
* 插入操作:INSERT。
* 更新操作:UPDATE。
* 删除操作:DELETE。
* 单行查询操作:SELECT ... INTO ...。
当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一个DML操作或单行SELECT操作的游标属性。所以通常在刚刚执行完操作之后,立即使用SQL游标名来访问属性。游标的属性有四种,如下所示:
- 隐式游标
* sql%found (布尔类型,默认值为null)INSERT、UPDATE、DELETE 成功返回TRUE
* sql%notfound(布尔类型,默认值为null)INSERT、UPDATE、DELETE 不成功返回TRUE
* sql%rowcount(数值类型默认值为0)返回INSERT、UPDATE、DELETE 影响的行数
* sql%isopen(布尔类型)隐式游标返回FALSE,
2. 显式游标
* 声明游标 cursor c_customer is select * from customers;
* 打开游标 open c_customer;
* 获取游标 fetch c_customers into c_addr,c_name,c_salary;
* 关闭游标 close c_customers;
declare c_id customers.id%type;
c_name customers.name%type;
c_addr customers.address%type;
cursor c_customers is select id,name,address from customers;
begin
open c_customers;
loop
fetch c_customers into c_id,c_name,c_addr;
exit when c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);
end loop;
close c_customers;
end;
- 异常处理
- 异常声明 : exception_name exception;
- 抛出异常 : raise exception_name;
- 捕获异常 : when exception_name then…
DECLARE
c_id customers.id%type := &c_id; -- 接收用户输入的值,运行的时候会弹出一个输入框。
c_name customers.name%type;
c_addr customers.address%type;
-- user defined exception
ex_invalid_id EXCEPTION;
BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id;
ELSE
SELECT name, address INTO c_name, c_addr
FROM customers
WHERE id = c_id;
DBMS_OUTPUT.PUT_LINE ('Name: '|| c_name);
DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
END IF;
EXCEPTION
WHEN ex_invalid_id THEN
dbms_output.put_line('ID must be greater than zero!');
WHEN no_data_found THEN
dbms_output.put_line('No such customer!');
WHEN others THEN
dbms_output.put_line('Error!');
END;
TIPS
- dbms_output.put_line() 输出日志