程序调用->PL/SQL存储程序->Oracle服务器编译加载->
->PL/SQL引擎处理程序内存结构和逻辑程序流
->SQL引擎向数据库提出数据请求
一个PL/SQL块的基本形式:
[DECLARE]
-- Put variables Here
BEGIN
-- Put Program Here
[EXCEPTION]
-- Put exception handlers here
END;
字符集规则及使用字符:
声明部分对变量赋值:
Variable_name variable_type := value;
在程序中对对变量赋值:
Variable_name := value;
每一部分小的赋值程序
-- Declaration section of the program
declare
l_counter number :=0; -- initiate value to 0
l_today date :=sysdate; -- assign system date to variable
l_name varchar2(50); -- variable is defined but has no value
l_seq_val number :=ian_seq.nextval; -- assign the next sequence value to the variable
--
-- Execution section of the program
begin
l_counter :=l_counter + 1;
l_name := 'LUCY THE CAT';
-- Error handling section of the programming
exception
-- Generic error handling to handle any type of error
-- print out an error message
raise_application_error (-20100,'error#' ||sqlcode||'desc:' sqlerrm)
--
end;
变量sqlcode: 表示oracle错误号
变量sqlerrm: 表示oracle错误信息
声明部分定义varchar2,要有分号:
Variable_name varchar2(max_length);
数字类型声明格式:
Number_field number(length,decimal_places);
length 表示有效位数 1-38
decimal_places 表示小数点以后的位数
子类型:DECIMAL,FLOAT,REAL
日期类型声明格式:
Date_variable date;
默认格式:DD-MON-YY
Declare
L_start_date date;
Begin
L_start_date :='29-SEP-05';
L_start_date :=to_date('29-SEP-2083','DD-MON-YYYY'); -- Sets variable to September 29,2083
L_start_date :=to_date('09-JUN-91:13:01','DD-MON-YY:HH24:MI'); --Sets variable to June 9,1991,1:01 p.m
End;
布尔类型:
在PL/SQL中只能用true/false
根据表的列定义设置一个变量:
v_product_id products.prod_id%TYPE;
%TYPE 声明的变量获得与字段相同的数据类型,v_product_id的数据类型与表products中的字段.prod_id类型相匹配
set serveroutput on;
Declare
L_start_date date;
Begin
L_start_date := '29-9月-2005';
dbms_output.put_line(l_start_date); --show date
End;
/
注意:
1. 查看系统的日期命令,发现日期格式是29-9月-2005,是中文格式
select sysdate from dual;
2.新版本中, putline更新为put_line了。
Declare
L_start_date date;
Begin
L_start_date := '29-9月-2005';
dbms_output.put_line(l_start_date); --show date
L_start_date :=to_date('14-9月-2063','DD-MON-YYYY');
dbms_output.put_line(l_start_date); --show date
L_start_date :=to_date('09-9月-91:13:01','DD-MON-YY:HH24:MI');
dbms_output.put_line(l_start_date); --show date
End;
/
把数据集成到PL/SQL代码中
用select语句对变量进行赋值:
select prod_name into v_prod_name from products;
declare
v_prod_name varchar2(50);
begin
select prod_name into v_prod_name from products where rownum=1;
dbms_output.put_line(v_prod_name);
end;
/
select prod_name,prod_list_price,prod_min_price from products where rownum<10;
隐式游标:在程序可执行部分的SQL语句,且有一个into语句,但是程序运行速度慢
显示游标:在程序的声明部分声明的select语句,在程序执行过程之前已经准备好SQL语句,查询结果超过一行
游标声明(显示游标)
cursor cursor_name is select_statement;
注:游标名是未声明的变量,不能给游标名赋值或者用于表达式中
打开游标:使用游标的值之前,要打开游标
open cursor_name;
从游标提取数据:从游标得到一行数据,使用命令fetch。每一次提取数据后,游标都指向结果集的下一行
fetch cursor_name into varibale_name;
关闭游标
close cursor_name;
eg1.
declare
v_prod_name varchar2(50);
cursor get_data is select prod_name from products;
begin
open get_data;
fetch get_data into v_prod_name;
dbms_output.put_line(v_prod_name);
close get_data;
end;
/
eg2.
set serverinput on
declare
v_ename emp.ename%TYPE;
v_salary emp.salary%TYPE;
cursor c_emp is select ename,salary from emp;
begin
open c_emp;
fetch c_emp into v_ename,v_salary;
dbms_output.put_line('Salary of employee'||v_ename||'is'||v_salary);
fetch c_emp into v_ename,v_salary;
dbms_output.put_line('Salary of employee'||v_ename||'is'||v_salary);
close c_emp;
end;
/
注:
set serverinput on 的功能是打开oracle自带的输入方法dbms_output
%TYPE 变量自动获取与字段相同的数据类型
|| 字符串连接
5.4.3 游标for循环
结果集中包含多行记录,用for循环可以提取多行
LOOP基本语法
[<>] --可选标签
LOOP
statement;
END LOOP[<>]
FOR…LOOP结构
[<>]
FOR index_name IN
[REVERSE]
lower_bound..upper_bound
LOOP
stetement;
END LOOP[<>]
[说明:]
index_name:循环计数器,是一个变量
REVERSE:可选,指定循环方式。默认由下标界lower_bound到上标界upper_bound,上标和下标界之间不能省略".."
eg.
--for..loop
declare
v_rlt number(8);
begin
for vrlt in -3..3
loop
dbms_output.put_line('v_rlt='||vrlt);
end loop;
dbms_output.put_line('for循环结束!');
end;
/
eg2.
set serveroutput on
declare
v_prod_name varchar2(50);
cursor cur_get_data is select prod_name from products;
begin
for i in cur_get_data
LOOP
dbms_output.put_line(i.prod_name);
END LOOP;
end;
/
注:
在for循环期间,用循环变量名i和游标声明中定义的列明连在一起,可以引用游标中的列
dbms_profiler 工具包,可以查看各个模块的性能,如查询运行时间等。