PL/SQL也是一种程序语言,叫做过程化SQL语言,PL/SQL是Oracle对SQL语言的扩展,在普通的SQL语句的使用上增加了编程语言的特点,所以PL/SQL把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断,循环等操作实现复杂的功能或者计算.
打印输出:hello world
SET SERVEROUTPUT ON; --开启打印功能 BEGIN --过程开始 DBMS_OUTPUT.put_line('hello world');--过程代码 END;--过程结束 /定义变量
注意:PL/SQL中赋值符号为":=",键盘输入的符号为"&",字符串连接用"||",如果声明了变量但没有赋值默认为空
DECLARE -- 声明 num NUMBER; --定义变量 BEGIN num:=#--等待键盘输入num的值 DBMS_OUTPUT.put_line('num的值为:'||num); END; /定义常量
注意:常量使用CONSTANT修饰,而且必须有初始值且常量不能重新赋值.
DECLARE num CONSTANT NUMBER :=120 ; ---常量必须赋初值, BEGIN DBMS_OUTPUT.put_line('常量num的值为:'||num); END; /%TYPE与%ROWTYPE定义的变量类型
DECLARE v_no emp.empno%TYPE; --表示num的类型为emp表中的empno的字段类型 result emp%ROWTYPE; --表示这个变量可以接受emp表中的所有字段的数据 BEGIN v_no:=&empno; SELECT * INTO result FROM emp WHERE empno = v_no; DBMS_OUTPUT.put_line('姓名:'||result.ename||' , 部门编号:'||result.deptno||' , 薪水:'||result.sal||' , 领导编号:'||result.mgr||' , 职位:'||result.job); END; /IF的使用
DECLARE num NUMBER; BEGIN SELECT COUNT(*) INTO num FROM emp; IF num > 10 THEN DBMS_OUTPUT.put_line('数据量大于10'); END IF; --表示if结束 END; /IF ELSE
DECLARE num NUMBER; BEGIN num:=# IF num > 10 THEN DBMS_OUTPUT.put_line('数据大于10'); ELSE DBMS_OUTPUT.put_line('数据小于10'); END IF; --表示if结束 END; /ELSIF
DECLARE num NUMBER; BEGIN num:=# IF num > 10 THEN DBMS_OUTPUT.put_line('数据大于10'); ELSIF num = 10 THEN DBMS_OUTPUT.put_line('数据等于于10'); ELSE DBMS_OUTPUT.put_line('数据小于10'); END IF; --表示if结束 END; /存储过程Procedure是一组为了完成特定功能的SQL语句集合,之前的pl/sql只能编写一次执行一次或多次,但是不能将其保存起来下次使用.如果要让其继续生效则应该将这个过程存储起来,于是就出现了存储过程的概念,经编译后存储在数据库中,用户通过存储过程的名称并给出参数来调用.
调用过程输出 hello world
--创建存储过程 CREATE OR REPLACE PROCEDURE say_hello AS BEGIN DBMS_OUTPUT.put_line('hello world'); END; / --使用命令执行存储过程 EXEC say_hello()有参数参与的存储过程
--创建存储过程 CREATE OR REPLACE PROCEDURE print_add( a NUMBER , b NUMBER ) AS BEGIN DBMS_OUTPUT.put_line('a+b'||(a+b)); END; / --使用命令执行存储过程 EXEC print_add(10,20);存储过储的输出和输入参数
如果过程的参数是IN修饰的则表示该参数需要在调用的时候传递进来,如果是OUT修饰的则表示可以被返回,如果不写默认就是IN
--创建存储过程 CREATE OR REPLACE PROCEDURE print_sum( a IN NUMBER , --这是一个输入参数,表示调用过程时需要传递进来 b IN NUMBER , --这是一个输入参数,表示调用过程时需要传递进来 c OUT NUMBER --这是一个输出但是,表示这个参数可以被返回 ) AS result NUMBER; --这是过程的局部变量 BEGIN result := a+b; c := result*10; END; / --执行 DECLARE r NUMBER; BEGIN print_sum(10,20,r); DBMS_OUTPUT.put_line('返回的r值为:'||r); END; /触发器在数据库中是一独立的对象存储的,它与存储过程和函数不同的是:存储过程与函数需要用户调用才会执行,而触发器是由一个事件来触发运行的.即触发器是当某个事件发生时自动运行,并且,触发器不能接收参数.
Oracle的事件是指对数据库的表进行的,INSERT,UPDATE,DELETE操作或对视图进行类似的操作.
语句级触发器是对每个DML语句执行一次,如果一条INSERT语句在表中插入500行,那么这个表上的触发器只执行一次.
--创建触发器 CREATE OR REPLACE TRIGGER emp_trigger BEFORE INSERT OR DELETE --在增加或删除数据之前触发 ON emp --表示触发器建立在emp数据表上 DECLARE --声明变量 v_date VARCHAR2(30); BEGIN SELECT TO_CHAR(SYSDATE,'day') INTO v_date FROM dual; --获得当前是星期几 IF v_date ='星期六' OR v_date ='星期日' THEN --RAISE_APPLICATION_ERROR 抛出错误在 -20999 到 -20000 之间 RAISE_APPLICATION_ERROR(-20001,'周末不能办理入职或离职手续!!'); END IF; END; /添加数据测试
对于行级触发器,只要有一条数据被影响就会触发一次
--创建触发器 CREATE OR REPLACE TRIGGER emp_trigger BEFORE INSERT --在增加数据之前触发 ON emp --表示触发器建立在emp数据表上 FOR EACH ROW --表示是行级的触发器,不写就表示是表级触发器 BEGIN IF :new.sal>10000 THEN RAISE_APPLICATION_ERROR(-20001,'给的工资太高了,公司要破产的!!!!'); ELSIF :new.sal<1000 THEN RAISE_APPLICATION_ERROR(-20002,'给的工资太低了!!!!!'); END IF; END; /添加人员触发触发器
利用触发器实现级联更新
--创建触发器 CREATE OR REPLACE TRIGGER dept_trigger BEFORE UPDATE OF deptno --指定了更新demp表中的deptno字段之前会触发触发器 ON dept FOR EACH ROW BEGIN UPDATE emp SET deptno = :new.deptno WHERE deptno = :old.deptno; END; /修改了dept表中的deptno字段,emp表中的字段也会跟着变化
注意: 在INSERT是:new表示新插入的数据,在UPDATE时,:new表示要替换的数据,:old表示原来要被更改的数据,
