整体结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
set serveroutput on
declare --外层程序块头
out_text1 varchar2(50);
begin
declare --内层程序块头
out_text2 varchar2(50);
begin
out_text2:='内层程序块';
dbms_output.put_line(out_text2);
end; --内层程序块尾
out_text1:='外层程序块';
dbms_output.put_line(out_text1);
end; --外层程序块尾
/ --程序块结束标记

样例

标识符

  • 以字母开头
  • 不区分大小写
  • 不能超过30单位长度
  • 不能有‘-’和空格
  • 不能是SQL关键字
    在SQL*Plus查看SQL关键字
    1
    help reserved words

标量和变量

量名 备注
NUMBER(p,s) p为数据长度,s为小数个数,皆为可选
PLS_INTEGER 类似,-2^31~2^31,速度快,CUP利用率高,溢出触发异常
BINARY_INTEGER 类似pls_number,溢出赋值给number且未超出number范围时,不会异常
POSITIVE 正整数
NATURAL 自然数
DATE 日期型
BOOLEAN 布尔值
CHAR 字符型
VARCHAR 可变长度字符串
VARCHAR2 Oracle自定义的一种类型,是作为以后升级后的兼容后门。varchar就不一定兼容了。

常量

1
PI CONSTANT NUMBER(9) := 3.1415926;

NUMBER详解——》传送门

强制转换到字符型

1
TO_CHAR(XXX)

混搭SQL语句

1
2
3
4
5
6
7
8
9
10
set serveroutput on
declare
a number(4);
begin
select count(编号)
into a
from Student;
dbms_output.put_line(a);
end;
/

TYPE和ROWTYPE类型的变量

TYPE

先去查询目标表的列属性,然后将该属性类型设置给变量。

1
2
3
4
5
6
7
8
9
10
set serveroutput on
declare
a Student.sname%TYPE;
begin
select sname
into a
from Student;
dbms_output.put_line(a);
end;
/

ROWTYPE

形成一个RECODE,类似与c++的struct,其中每一个值都是TYPE类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
set serveroutput on
declare
a Student%ROWTYPE;
begin
select *
into a
from Student;
dbms_output.put_line(a.sid);
dbms_output.put_line(a.sname);
dbms_output.put_line(a.ssex);
dbms_output.put_line(a.sage);
end;
/

复合变量

记录类型

语法

1
2
3
4
5
TYPE RECORD_NAME IS RECORD(
feildname1 data_type [not null] [:=defualt_value],
···
feildnamen data_type [not null] [:=defualt_value],
)

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
set serveroutput on
declare
TYPE Sturecord IS RECORD(
ID VARCHAR2(20)
NAME VARCHAR2(20)
SEX CHAR
AGE INTEGER
);
a Sturecord;
begin
select sid,sname,ssex,sage
into a
from Student
where sid=1;
dbms_output.put_line(a.ID);
dbms_output.put_line(a.NAME);
dbms_output.put_line(a.SEX);
dbms_output.put_line(a.AGE);
end;
/

注意

  • select语句是按顺序逐个查询的,所以select后列的顺序要与record的中类型的顺序要匹配
  • 假如record_a与record_b除了名字之外完全一样,a类型的值也不能赋给b类型。

记录表类型

  • 记录类型一个变量只能存一行信息,记录表类型可以存多行信息。
  • 不会存储入数据库,只在内存中生存。

语法

1
2
TYPE TABLE_NAME IS TABLE OF DATA_TYPE [NOT NULL]
INDEX BY BINARY_INTEGER; --自动建立索引

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
set serveroutput on
declare
TYPE a IS TABLE OF Student%ROWTYPE;
begin
select *
into a
from Student;
dbms_output.put_line(a(1).sid);
dbms_output.put_line(a(1).sname);
dbms_output.put_line(a(1).ssex);
dbms_output.put_line(a(1).sage); --只第一行的数据。
end;
/

其它功能

  • count 计数
  • delete 删除行
  • first 第一个索引值
  • next 下一个索引值
  • last 最后一行记录的索引值

一个坑

做了一个大坑,今天终于填上了。在 Simple PL/SQL 对游标的理解 一讲中我有一个不能实行的问题,还一直以为是游标或者本地读取失败的BUG。结果是
不能直接对表变量赋值,赋值需要使用下标,如下面的的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
set serveroutput on
declare
type course_table is table of course%rowtype index by binary_integer;
fku course_table;
v_num number:=0;
cursor cur_cou is select * from course;
begin
for tmp in cur_cou loop
v_num:=v_num+1;
select * into fku(v_num) from course where tmp.cid=cid ;
end loop;
if fku.count=0 then
dbms_output.put_line('没有记录');
else
dbms_output.put_line('有'||fku.count||'条记录');
end if;
end;
/

坑