PL/SQL是过程语言与结构化查询语言结合而成的编程语言。
PL/SQL支持SQL:
数据操纵命令
事物控制命令
游标控制
SQL函数和SQL运算符
可移植性,可运行在任何OS和平台上的Oracle数据库
更佳的性能,PL/SQL经过编译执行!
※与SQL紧密集成,简化数据处理
支持所有SQL数据类型
支持NULL值
支持%TYPE和%ROWTYPE属性类型
※安全性,可以通过存储过程限制用户对数据的访问
在执行期间,将所有的SQL语句传递给SQL语句执行器组件执行。相对于逐条发送一组SQL语句,PL/SQL的打包传输,减少了网络流量。
PL /SQL引擎驻留在Oracle数据库中。
PL/SQL分为三部分:
声明部分(可选)
执行部分(必需)
异常处理部分(可选)
------------------------------------
| [DECLARE |
| Declarations |
| ] |
| BEGIN |
| executable statements |
| [EXCEPTION |
| handlers |
| ] |
| END; |
|-----------------------------------
DECLARE // 声明语句
v_sal NUMBER(5);
BEGIN // 执行语句
SELECT sal INTO v_sal FROM emp // INTO sal给变量v_sal赋值
WHERE empno=7369;
IF v_sal<2000 THEN
UPDATE emp SET sal=sal+500
WHERE empno=7369;
END IF;
EXCEPTION /* 异常处理语句 */
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('出错:'||SQLERRM);
END;
声明变量与常量的语法:
Variable_name[CONSTANT]datatype[NOT NULL]
[:=value|DEFAULT value]; // 是给变量附初值
其中variable_name是要声明的变量名称。
FETCH INTO // 给多行附初值
:=
SELECT INTO
DECLARE
v_deptno number()
在SQL*Plus下执行命令方法:
进入输入
SQL>set serveroutput on;
SQL>DECLARE
v_deptno NUMBER(5):=&deptno; --从键盘输入方式赋值
v_sumsal NUMBER(7,2);
BEGIN
SELECT deptno,SUM(sal) INTO v_deptno,v_sumsal
FROM emp GROUP BY deptno HAVING deptno=v_deptno;
dbms_output.put_line('部门 '||v_deptno||' 的总工资是:'||v_sumsal);
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('编号不存在!');
END;
键入:/
--->程序开始执行!
变量以v_开头
常量以c_开头
游标变量以_cursor结尾
异常表示e_开头
表类型以_table_type结尾
表以_table结尾
记录类型以_recode结尾
变量作用范围:
变量作用范围是在引用变量的程序单元内,即从声明变量开始到该快结束
DECLARE
注释类型:-- /**/
-- "我"有很多个
/* "我"有很多个 */
属性类型:
%TYPE--引用变量和数据库列的数据类型
%ROWTYPE--提供表示表中一行的记录类型
属性优点:
不需要知道被引用的表列的具体类型
可以实时改变类型
variable table_name column_name%TYPE
自定义变量 表名 表列字段
t_empno emp.empno%TYPE
个数和数据类型不需要知道
个数和数据类型实时改变
record_variable_name table_name%ROWTYPE
rec emp%ROWTYPE
引用的时候与CPP中类引用成员很相似!
eg:rec.ename --引用了其中的一个字段ename
因此在需要使用一行的时候 很方便!可以直接对整行进行操作!
引用的时候可以只取出自己想要进行操作的字段!
以下一段代码在PL/SQL Developer中执行:
DECLARE
v_empno emp.empno%TYPE:=&empno; -- 变量v_empno存储从终端输入的值
rec emp%ROWTYPE; -- 变量拥有emp所有字段的类型
BEGIN -- 程序执行开始↓
SELECT * INTO rec FROM emp
WHERE empno=v_empno; -- 判断输入是否与表中empno匹配
Dbms_Output.put_line(
'姓名:'||rec.ename
||'工资:'||rec.sal
);
EXCEPTION
WHEN OTHERS THEN
Dbms_output.put_line('没有这个员工!');
END;
记录类型:
用户自定的数据类型,使用自定义类型去声明相应的程序变量
TYPE 记录类型名 IS RECODE(filed_definition_list);
to_char(SYSDATE,'yyyy-mm-dd') // 只负责转换时间类型的输出格式!
to_date('字符串',yyyy-mm-dd) // 只负责将字符串转换为时间类型,不负责输出格式!
//IF-THEN
IF<表达式>THEN
SQL语句;
END IF;
// IF-THEN-ELSE
IF<表达式>THEN
SQL语句;
ELSE
其他语句;
END IF;
//IF-THEN-ELSIF
IF<表达式>THEN
SQL语句;
ELSIF<表达式>THEN
其他语句;
ELSIF<表达式>THEN
其他语句;
END IF;
eg:
DECLARE
v_empno emp.empno%TYPE:=&empno;
v_salary emp.sal%TYPE;
v_comment VARCHAR2(35);
BEGIN
SELECT sal INTO v_salary FROM emp
WHERE empno=v_empno;
IF v_salary<1500 THEN
v_comment:='Fairly less';
ELSIF v_salary<3000 THEN
v_comment:='A little more';
ELSE
v_comment:='Lots of salary';
END IF;
DBMS_OUTPUT.PUT_LINE(v_comment);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('你需要的数据不存在!');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('发生其他错误!');
END;
// case 语句 用于根据单个变量或表达式与多个值进行比较
CASE expr <'&grade'> // ''&''符号表示从键盘输入!
WHEN 1 THEN Action1;
WHEN 2 THEN Action2;
......
WHEN N THEN ActionN;
ELSE ActionOther;
END CASE;
// case 表达式
CASE expr<job> //具体的值
WHEN exp1 THEN Action1;
WHEN exp2 THEN Action2;
ELSE ACtionOther;
END
// 搜索case表达式
CASE // 此处没有参数
WHEN condition1 THEN Action1; //condition1 < sal>=2500 >
WHEN condition2 THEN Action2;
ELSE ACtionOther;
END
// 循环控制
①无条件循环LOOP-EXIT-END
LOOP
要执行的语句;
EXIT WHEN<条件语句> /* 满足条件 退出循环 */
END LOOP
DECLARE
num NUMBER:=0;
BEGIN
LOOP
num:=num+1;
Dbms_Output.put_line('num当前值为:'||num);
EXIT WHEN num=10;
END LOOP;
END;
②根据条件循环WHILE-LOOP-END
WHILE<布尔表达式>LOOP
要执行的语句;
END LOOP;
DECLARE
num NUMBER;
BEGIN
num:=0;
WHILE num<20 LOOP
num:=num+1;
Dbms_Output.put_line('num的当前值为:'||num);
END LOOP;
END;
③数字式循环语法FOR-IN-LOOP-END
FOR 循环计数器 IN [REVERSE] 下限..上限 LOOP // REVERSE 表示自减 IN 后的数字必须是从小到大的整数!
要执行的语句;
END LOOP
eg:
BEGIN
FOR num IN 1..10 LOOP
Dbms_Output.put_line('num当前的值:'||num);
END LOOP;
END;
if逻辑规则:
规则1:每个if语句都有自己的then,以if开始的语句行不跟语句结束符";"
规则2:每个if语句块以相应的end if 结束
规则3:每个if语句有且只有一个else
规则4:else语句行后面不跟语句结束符
规则5:elsif 无匹配的end if