Procedural Language和SQL的结合体。通过增加变量、控制语句,使我们可以写些逻辑更加复杂的数据库操作
语句框架组成
declare – 可选 声明各种变量或游标的地方。 begin – 必要 开始执行语句。 --单行注释语句用两个连在一起的‘-’表示。 /*多行注释语句, 可以换行*/ exception – 可选 出错后的处理。 end; – 必要(请注意end后面的分号)
简单helloworld程序
1 declare 2 v_temp number(6):=123; /* := 是一个赋值符号 */ 3 begin 4 dbms_output.put_line(‘middle‘); 5 dbms_output.put_line(v_temp); 6 end;
注意
要想显示程序的东西需要设置环境
set serveroutput off -->关闭输出(默认关闭) set serveroutput on -->打开输出
基本数据类型
-
- Number 数字型
- Int 整数型
- Pls_integer 整数型,产生溢出时出现错误
- Binary_integer 整数型,表示带符号的整数
- Char 定长字符型,最大255个字符
- Varchar2 变长字符型,最大2000个字符
- Long 变长字符型,最长2GB
- Date 日期型
- Boolean 布尔型(TRUE、FALSE、NULL三者取一)
- %type 表示不需要知道具体的一个字段类型,与指定的字段类型一致即可。例如:v_empno emp.empno%type;
- %rowtype 与表结构完全一致 %rowtype 举例:
1 declare 2 v_tt emp%rowtype; 3 begin 4 select * into v_tt from emp where empno=7521; 5 dbms_output.put_line(v_tt.job); 6 dbms_output.put_line(v_tt.sal); 7 end; 8 9 输出:SALESMAN 10 1250
varray
定义语法
TYPE VARRAYNAMEIS VARRAY(SIZE) OF ELEMENTTYPE [NOT NULL];
-
- 其中,varrayname是VARRAY数据类型的名称,size是正整数,表示可以容纳的成员的最大数量,每个成员的数据类型是elementtypeo默认时,成员可以取空值,否则需要使用NOT NULL加以限制。
- 数组是具有相同数据类型的一组成员的集合。每个成员都有一个唯一的下标,它取决于成员在数组中的位置。在PL/SQL中,数组数据类型是VARRAY(variable array,即可变数组)。
1 declare 2 type my_varray is varray(2) of varchar2(12) not null; 3 varray_my my_varray; 4 begin 5 varray_my:=my_varray(‘dsa‘,‘sdafds‘); 6 dbms_output.put_line(varray_my(1)); 7 end;
-
- 如果初始化数量大于设定的大小,会报下标超出限制异常
- 如果初始化数量小于设定的大小,会按照初始化数量进行设定大小,访问不存在数据的下标(即使在设定范围内).也会报异常
1 DECLARE 2 --定义一个最多保存5个VARCHAR(25)数据类型成员的VARRAY数据类型 3 TYPE reg_varray_type IS VARRAY(5) OF VARCHAR(25); 4 --声明一个该VARRAY数据类型的变量 5 v_reg_varray REG_VARRAY_TYPE; 6 BEGIN 7 --用构造函数语法赋予初值 8 v_reg_varray := reg_varray_type 9 (‘中国‘, ‘美国‘, ‘英国‘, ‘日本‘, ‘法国‘); 10 DBMS_OUTPUT.PUT_LINE(‘地区名称:‘||v_reg_varray(1)||‘、‘ 11 ||v_reg_varray(2)||‘、‘ 12 ||v_reg_varray(3)||‘、‘ 13 ||v_reg_varray(4)); 14 DBMS_OUTPUT.PUT_LINE(‘赋予初值NULL的第5个成员的值:‘||v_reg_varray(5)); 15 --用构造函数语法赋予初值后就可以这样对成员赋值 16 v_reg_varray(5) := ‘法国‘; 17 DBMS_OUTPUT.PUT_LINE(‘第5个成员的值:‘||v_reg_varray(5)); 18 END;
table
-
- 定义记录表(或索引表)数据类型。它与记录类型相似,但它是对记录类型的扩展。它可以处理多行记录,类似于C语言中的二维数组,使得可以在PL/SQL中模仿数据库中的表。
定义记录表类型的语法如下:
TYPE TABLE NAME IS TABLE OF ELEMENT_TYPE [NOT NULL] INDEX BY [BINARYINTEGER|LSINTEGER|VARRAY2];
-
- 关键字INDEX BY表示创建一个主键索引,以便引用记录表变量中的特定行。 BINARY_INTEGER的说明
- 如语句:TYPE NUMBERS IS TABLE OF NUMBER INDEX BY BINARYINTEGER;其作用是,加”INDEX BYBINARYINTEGER ”后,NUMBERS类型的下标就是自增长,NUMBERS类型在插入元素时,不需要初始化,不需要每次EXTEND增加一个空间。
- 而如果没有这句话“INDEXBY BINARY_INTEGER”,那就得要显示对初始化,且每插入一个元素到NUMBERS类型的TABLE中时,都需要先EXTEND。
1 --table 不能像varray一样初始化数据,只能一个一个赋值 2 declare 3 type table_my is table of number not null index by binary_integer;-- by binary_integer表示创建一个主键索引,以便引用记录表变量中的特定行。 4 my_table table_my; 5 begin 6 my_table(1):=23; 7 my_table(2):=24; 8 my_table(3):=24; 9 dbms_output.put_line(my_table(1)); 10 end; 11 12 结果: 23 13 14 15 ---table结合rowtype的使用 16 declare 17 type table_my is table of emp%rowtype index by binary_integer; 18 19 my_table table_my; 20 begin 21 select * BULK COLLECT into my_table from emp ; 22 for i in my_table.first..my_table.last loop 23 dbms_output.put_line(my_table(i).empno||‘==‘||my_table(i).ename||‘==‘||my_table(i).job); 24 end loop; 25 end; 26 27 结果:1357==oracle== 28 7369==SMITH==CLERK 29 7499==ALLEN==SALESMAN 30 ...
table常见方法
record
-
- 定义记录数据类型。它类似于C语言中的结构数据类型(STRUCTURE),PL/SQL提供了将几个相关的、分离的、基本数据类型的变量组成一个整体的方法,即RECORD复合数据类型。在使用记录数据类型变量时,需要在声明部分先定义记录的组成、记录的变量,然后在执行部分引用该记录变量本身或其中的成员。
定义记录数据类型的语法如下:
TYPE RECORDNAME IS RECORD(
V1 DATATYPE1 [NOT NULL][:=DEFAULTVALUE],
V2 DATATYPE2 [NOT NULL][:=DEFAULTVALUE],
VN DATATYPEN [NOT NULL][:=DEFAULT_VALUE]
);
1 ---record实现多列多行查询 2 declare 3 type my_record is record( 4 v_empno emp.empno%type, 5 v_ename emp.ename%type, 6 v_job emp.job%type 7 ); 8 type my_table is table of my_record index by binary_integer; 9 table_my my_table; 10 begin 11 select empno,ename,job BULK COLLECT into table_my from emp ; 12 for i in table_my.first..table_my.last loop 13 dbms_output.put_line(table_my(i).v_empno||‘==‘||table_my(i).v_ename||‘==‘||table_my(i).v_job); 14 end loop; 15 end; 16 结果同上一个table
boolean
-
- 布尔值只有TRUE, FALSE及 NULL 三个值
单行取值select
语法格式
select 字段 into 变量 from 表 where 条件
-
- 将查询到得数据放入变量中
- 确保必须有唯一一个字段
- 不能存在多个值,也不能为空,否则报错
- 将查询到得数据放入变量中
异常处理,一级自定义异常
语法格式
EXCEPTION
WHEN firstexception THEN code to handle first exception
WHEN secondexception THEN code to handle second exception
WHEN OTHERS THEN code to handle others exception
END;
-
- 异常处理可以按任意次序排列,但 OTHERS 必须放在最后
常见异常
自定义异常:
1 declare 2 v_exception exception; 3 v_sal emp.sal%type; 4 begin 5 select sal into v_sal from emp where empno=7521; 6 if v_sal>1000 then 7 raise v_exception; 8 else 9 dbms_output.put_line(‘还可以‘); 10 end if; 11 exception 12 when v_exception then 13 dbms_output.put_line(‘钱太少啦‘); 14 end; 15 16 结果:钱太少啦
自定义错误----------------
1 declare 2 v_sal emp.sal%type; 3 begin 4 select sal into v_sal from emp where empno=7521; 5 if v_sal>1000 then 6 raise_application_error(‘-20000‘,‘工资太低啦‘); 7 else 8 dbms_output.put_line(v_sal); 9 end if; 10 11 end; 12 结果:会弹出弹出框错误
PLSQL嵌套DML的 insert update delete
- 直接使用
- DML语句起作用或者回退的话,需要显式的调用commit或者rollback
- sql%rowcount属性来记录最后一条SQL语句影响了多少 条记录
insert
1 declare 2 v_empno emp.empno%type:=&s_empno; 3 begin 4 insert into emp(empno,ename) values(v_empno,‘张三‘); 5 if v_empno>4 then 6 rollback; 7 raise_application_error(‘-20000‘,‘不能这样插滴~~‘); 8 end if; 9 end; 10 结果弹出错误.
update和delete用法同上
execute immediate的用法
-
- 拼接字符串:标准的sql语句
- execute immediate +字符串
- execute immediate +字符串 into 变量 using 参数
- execute immediate 执行ddl语句或dml语句或dcl语句 (标准的sql语句)
1 ----1--- 2 declare 3 v_sql varchar2(122):=‘insert into emp(empno,ename) values(:a,:b)‘; 4 begin 5 execute immediate v_sql using 111,‘shfdk‘; 6 commit; 7 end; 8 9 ----2----- 10 declare 11 v_sql varchar2(122) := ‘select ename from emp where sal=:a‘; 12 v_name emp.ename%type; 13 begin 14 execute immediate v_sql 15 into v_name 16 using 800; 17 dbms_output.put_line(v_name); 18 end;
循环结构
when
1 打印偶数 2 declare 3 v_num number(3, 0) := 0; 4 begin 5 loop 6 dbms_output.put_line(v_num); 7 v_num := v_num + 2; 8 exit when v_num = 100; 9 end loop; 10 end;
for循环
1 打印乘法口诀表 2 begin 3 for i in 1..9 loop 4 for j in 1..i loop 5 dbms_output.put(j||‘*‘||i||‘=‘||(i*j)||chr(9)); 6 if i=j then dbms_output.new_line(); 7 end if; 8 end loop; 9 end loop; 10 end;
时间: 2024-10-13 02:59:27