码迷,mamicode.com
首页 > 数据库 > 详细

PL/SQL编程基础

时间:2016-08-24 19:11:59      阅读:696      评论:0      收藏:0      [点我收藏+]

标签:

 

范例:编写不做任何工作的PL/SQL

BEGIN

NULL ;

END ;

/

 

范例:编写一个简单的PL/SQL程序

DECLARE

v_num NUMBER ; -- 定义一个变量v_num

BEGIN

v_num := 30 ; -- 设置v_num的内容

DBMS_OUTPUT.put_line(‘V_NUM变量的内容是:|| v_num) ;

END ;

/

 

范例:编写PL/SQL块,输入一个雇员编号,而后取得指定的雇员姓名

DECLARE

v_eno NUMBER ;

v_ename VARCHAR2(10) ;

BEGIN

v_eno := &empno ; -- 由键盘输入雇员编号

SELECT ename INTO v_ename FROM emp WHERE empno=v_eno ;

DBMS_OUTPUT.put_line(‘编号为:‘ || v_eno || ‘雇员的名字为:‘|| v_ename) ;

END ;

/

 

范例:定义变量不设置默认值

DECLARE

v_result VARCHAR2(30) ; -- 此处没有赋值

BEGIN

DBMS_OUTPUT.put_line(‘v_result的内容〖‘ || v_result || ‘‘) ;

END ;

/

 

范例:定义变量

DECLARE

v_resultA NUMBER := 100 ; -- 定义一个变量同时赋值

v_resultB NUMBER ; -- 定义一个变量没有设置内容

BEGIN

v_resultb := 30 ; -- 没有区分大小写

DBMS_OUTPUT.put_line(‘计算的结果是:‘ || (v_resultA + v_resultB) ) ;

END ;

/

 

范例:定义非空变量

DECLARE

v_resultA NUMBER NOT NULL := 100 ;  -- 定义一个非空变量v_resultA,同时赋值

BEGIN

DBMS_OUTPUT.put_line(‘v_resultA变量内容:‘ || (v_resultA) ) ;

END ;

/

 

范例:定义常量

DECLARE

v_resultA CONSTANT NUMBER NOT NULL := 100 ;  -- 定义一个常量同时赋值

BEGIN

DBMS_OUTPUT.put_line(‘v_resultA常量内容:‘ || (v_resultA) ) ;

END ;

/

 

范例:使用“%TYPE”定义变量

变量与指定的列的类型一致 采用%TYPE%

DECLARE

v_eno emp.empno%TYPE ; -- empno类型相同

v_ename emp.ename%TYPE ;  -- ename类型相同

BEGIN

DBMS_OUTPUT.put_line(‘请输入雇员编号:‘) ;

v_eno := &empno ; -- 由键盘输入雇员编号

SELECT ename INTO v_ename FROM emp WHERE empno= v_eno ;

DBMS_OUTPUT.put_line(‘编号为:‘ || v_eno || ‘雇员的名字为:‘|| v_ename) ;

END ;

/

 

范例:使用ROWTYPE装载

select into讲表中的一行记录设置到ROWTYPE类型的变量v_deptRow

可以使用v_deptRow. 出字段数据

DECLARE

v_deptRow dept%ROWTYPE ; -- 装载一行dept记录

BEGIN

SELECT * INTO v_deptRow FROM dept WHERE deptno=10 ;

DBMS_OUTPUT.put_line(‘部门编号:‘|| v_deptRow.deptno || ‘,名称:‘ || v_deptRow.dname || ‘,位置:‘ || v_deptRow.loc) ;

END ;

/

 

范例:通过自定义类型接收一行记录

DECLARE

TYPE dept_type IS RECORD (

dno dept.deptno%TYPE ,

dna dept.dname%TYPE ,

dlo dept.loc%TYPE) ; -- 定义一个新的类型

v_deptRow dept_type ; -- 装载一行dept记录

BEGIN

SELECT * INTO v_deptRow FROM dept WHERE deptno=10 ;

DBMS_OUTPUT.put_line(‘部门编号:‘|| v_deptRow.dno || ‘,名称:‘ || v_deptRow.dna || ‘,位置:‘ || v_deptRow.dlo) ;

END ;

/

 

范例:使用赋值运算符

将一个数值赋予指定数据类型的变量

DECLARE

v_info VARCHAR2(50) := ‘北京魔乐科技软件学院‘ ;

v_url VARCHAR2(50) ;

BEGIN

v_url := ‘www.mldnjava.cn‘ ;

DBMS_OUTPUT.put_line(v_info) ;

DBMS_OUTPUT.put_line(v_url) ;

END ;

/

 

范例:字符串连接 使用||

DECLARE

v_info VARCHAR2(50) := ‘北京魔乐科技软件学院‘ ;

v_url VARCHAR2(50) ;

BEGIN

v_url := ‘www.mldnjava.cn‘ ;

DBMS_OUTPUT.put_line(v_info || ‘,网址:‘ || v_url) ;

END ;

/

 

范例:使用关系运算符

<   >  <=  >=  !=  =  <>

is null   is not null

between  and  

in

like

DECLARE

v_url VARCHAR2(50) := ‘www.mldnjava.cn‘ ;

v_num1 NUMBER := 80 ;

v_num2 NUMBER := 30 ;

BEGIN

IF v_num1 > v_num2 THEN

DBMS_OUTPUT.put_line(‘1个数字比第2个数字大。‘) ;

END IF ;

IF v_url LIKE ‘%mldn%‘ THEN

DBMS_OUTPUT.put_line(‘网址之中包含mldn单词。‘) ;

END IF ;

END ;

/

 

范例:观察逻辑运算结果 IF  ENDIF

DECLARE

v_flag1 BOOLEAN := TRUE ;

v_flag2 BOOLEAN := FALSE ;

v_flag3 BOOLEAN ;

BEGIN

IF v_flag1 AND ( NOT v_flag2 ) THEN

DBMS_OUTPUT.put_line(‘v_flag1 AND ( NOT v_flag2 ) = TRUE‘) ;

END IF ;

IF v_flag1 OR v_flag3 THEN

DBMS_OUTPUT.put_line(‘v_flag1 OR v_flag3 = TRUE‘) ;

END IF ;

IF v_flag1 AND v_flag3 IS NULL THEN

DBMS_OUTPUT.put_line(‘v_flag1 AND v_flag3 的结果为NULL‘) ;

END IF ;

END ;

/

 

 

**********数据类型划分*********

 

范例:定义NUMBER变量

DECLARE

v_x NUMBER(3) ; -- 最多只能为3位数字

v_y NUMBER(5,2) ; -- 3位整数,2位小数

BEGIN

v_x := -500 ;

v_y := 999.88 ;

DBMS_OUTPUT.put_line(‘v_x = ‘ || v_x) ;

DBMS_OUTPUT.put_line(‘v_y = ‘ || v_y) ;

DBMS_OUTPUT.put_line(‘加法运算:‘ || (v_x + v_y)) ; -- 整数 + 浮点数 = 浮点数

END ;

/

 

范例:验证PLS_INTEGER操作

BINARY_INTEGER PLS_INTERGER -2147483648~2147483647 2进制

相比NUMBER占用范围更小,NUMBER为十进制 所以NUMBER相比性能低

当保存的数超出BINARY_INTEGER PLS_INTERGER范围时会转以NUMBER保存

DECLARE

v_pls1 PLS_INTEGER := 100 ;

v_pls2 PLS_INTEGER := 200 ;

v_result PLS_INTEGER ;

BEGIN

v_result := v_pls1 + v_pls2 ;

DBMS_OUTPUT.put_line(‘计算结果:‘ || v_result) ;

END ;

/

 

范例:验证BINARY_DOUBLE操作

BINARY_FLOATBINARY_DOUBLENUMBER节约空间并且范围更大

使用2进制保存数据,性能高

DECLARE

v_float BINARY_FLOAT := 8909.51F ;

v_double BINARY_DOUBLE := 8909.51D ;

BEGIN

v_float := v_float + 1000.16 ;

v_double := v_double + 1000.16 ;

DBMS_OUTPUT.put_line(‘BINARY_FLOAT变量内容:‘ || v_float) ;

DBMS_OUTPUT.put_line(‘BINARY_DOUBLE变量内容:‘ || v_double) ;

END ;

/

 

范例:观察表示范围的常量内容

DECLARE

BEGIN

DBMS_OUTPUT.put_line(‘1BINARY_FLOAT_MIN_NORMAL = ‘ || BINARY_FLOAT_MIN_NORMAL) ;

DBMS_OUTPUT.put_line(‘1BINARY_FLOAT_MAX_NORMAL = ‘ || BINARY_FLOAT_MAX_NORMAL) ;

DBMS_OUTPUT.put_line(‘1BINARY_FLOAT_MIN_SUBNORMAL = ‘ || BINARY_FLOAT_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line(‘1BINARY_FLOAT_MAX_SUBNORMAL = ‘ || BINARY_FLOAT_MAX_SUBNORMAL) ;

DBMS_OUTPUT.put_line(‘2BINARY_DOUBLE_MIN_NORMAL = ‘ || BINARY_DOUBLE_MIN_NORMAL) ;

DBMS_OUTPUT.put_line(‘2BINARY_DOUBLE_MAX_NORMAL = ‘ || BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line(‘2BINARY_DOUBLE_MIN_SUBNORMAL = ‘ || BINARY_DOUBLE_MIN_SUBNORMAL) ;

DBMS_OUTPUT.put_line(‘2BINARY_DOUBLE_MAX_SUBNORMAL = ‘ || BINARY_DOUBLE_MAX_SUBNORMAL) ;

END ;

/

 

范例:超过范围的计算

DECLARE

BEGIN

DBMS_OUTPUT.put_line(‘超过范围计算的结果:‘ ||

BINARY_DOUBLE_MAX_NORMAL * BINARY_DOUBLE_MAX_NORMAL) ;

DBMS_OUTPUT.put_line(‘超过范围计算的结果:‘ ||

BINARY_DOUBLE_MAX_NORMAL / 0) ;

END ;

/

 

**********字符型*********

范例:观察CHARVARCHAR2的区别

char定长 varchar2变长

oracle,VARCHAR2就是其他数据库的varchar

DECLARE

v_info_char CHAR(10) ;

v_info_varchar VARCHAR2(10) ;

BEGIN

v_info_char := ‘MLDN‘ ; -- 长度不足10

v_info_varchar := ‘java‘ ; -- 长度不足10

DBMS_OUTPUT.put_line(‘v_info_char内容长度:‘ || LENGTH(v_info_char)) ;

DBMS_OUTPUT.put_line(‘v_info_varchar内容长度:‘ || LENGTH(v_info_varchar)) ;

END ;

/

 

范例:验证NCHARNVARCHAR2

类似CHARVARCHAR2,但为UNICODE编码  中英文都为十六进制保存

目的是统一了字符/英文的长度,也浪费了空间

DECLARE

v_info_nchar NCHAR(10) ;

v_info_nvarchar NVARCHAR2(10) ;

BEGIN

v_info_nchar := ‘魔乐科技‘ ; -- 长度不足10

v_info_nvarchar := ‘java高端培训‘ ; -- 长度不足10

DBMS_OUTPUT.put_line(‘v_info_nchar内容长度:‘ || LENGTH(v_info_nchar)) ;

DBMS_OUTPUT.put_line(‘v_info_nvarchar内容长度:‘ || LENGTH(v_info_nvarchar)) ;

END ;

/

 

范例:使用LONGLONG RAW操作

UTL_RAW.cast_to_raw(‘’字符串)

DECLARE

v_info_long LONG ;

v_info_longraw LONG RAW ;

BEGIN

v_info_long := ‘魔乐科技‘ ; -- 直接设置字符串

v_info_longraw := UTL_RAW.cast_to_raw(‘JAVA高端培训‘) ; -- 将字符串变为RAW

DBMS_OUTPUT.put_line(‘v_info_long内容:‘ || v_info_long) ;

DBMS_OUTPUT.put_line(‘v_info_longraw内容:‘ || UTL_RAW.cast_to_varchar2(v_info_longraw)) ;

END ;

/

 

范例:使用ROWIDUROWID

DECLARE

v_emp_rowid ROWID ;

v_emp_urowid UROWID ;

BEGIN

SELECT ROWID INTO v_emp_rowid FROM emp WHERE empno=7369 ; -- 取得ROWID

SELECT ROWID INTO v_emp_urowid FROM emp WHERE empno=7369 ; -- 取得ROWID

DBMS_OUTPUT.put_line(‘7369雇员的ROWID = ‘ || v_emp_rowid) ;

DBMS_OUTPUT.put_line(‘7369雇员的UROWID = ‘ || v_emp_urowid) ;

END ;

/

 

 

***********日期类型***********

范例:定义DATE型变量

DECLARE

v_date1 DATE := SYSDATE ;

v_date2 DATE := SYSTIMESTAMP ;

v_date3 DATE := ‘19-9-1981‘ ;

BEGIN

DBMS_OUTPUT.put_line(‘日期数据:‘ || TO_CHAR(v_date1,‘yyyy-mm-dd hh24:mi:ss‘)) ;

DBMS_OUTPUT.put_line(‘日期数据:‘ || TO_CHAR(v_date2,‘yyyy-mm-dd hh24:mi:ss‘)) ;

DBMS_OUTPUT.put_line(‘日期数据:‘ || TO_CHAR(v_date3,‘yyyy-mm-dd hh24:mi:ss‘)) ;

END ;

/

 

范例:定义TIMESTAMP型变量

DECLARE

v_timestamp1 TIMESTAMP := SYSDATE ;

v_timestamp2 TIMESTAMP := SYSTIMESTAMP ;

v_timestamp3 TIMESTAMP := ‘19-9-1981‘ ;

BEGIN

DBMS_OUTPUT.put_line(‘日期数据:‘ || v_timestamp1) ;

DBMS_OUTPUT.put_line(‘日期数据:‘ || v_timestamp2) ;

DBMS_OUTPUT.put_line(‘日期数据:‘ || v_timestamp3) ;

END ;

/

 

范例:验证TIMESTAMP WITH TIME ZONE

DECLARE

v_timestamp TIMESTAMP WITH TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

 

范例:验证TIMESTAMP WITH LOCAL TIME ZONE

DECLARE

v_timestamp TIMESTAMP WITH LOCAL TIME ZONE := SYSTIMESTAMP ;

BEGIN

DBMS_OUTPUT.put_line(v_timestamp) ;

END ;

/

 

范例:定义INTERVAL YEAR TO MONTHS类型变量

DECLARE

v_interval INTERVAL YEAR(3) TO MONTH := INTERVAL ‘27-09‘ YEAR TO MONTH ;

BEGIN

DBMS_OUTPUT.put_line(‘时间间隔:‘ || v_interval) ;

DBMS_OUTPUT.put_line(‘当前时间戳 + 时间间隔:‘ || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line(‘当前日期 + 时间间隔:‘ || (SYSDATE + v_interval)) ;

END ;

/

 

范例:定义INTERVAL DAY TO SECOND类型变量

DECLARE

v_interval INTERVAL DAY(6) TO SECOND (3) := INTERVAL ‘8 18:19:27.367123909‘ DAY TO SECOND;

BEGIN

DBMS_OUTPUT.put_line(‘时间间隔:‘ || v_interval) ;

DBMS_OUTPUT.put_line(‘当前时间戳 + 时间间隔:‘ || (SYSTIMESTAMP + v_interval)) ;

DBMS_OUTPUT.put_line(‘当前日期 + 时间间隔:‘ || (SYSDATE + v_interval)) ;

END ;

/

 

范例:定义布尔型变量

DECLARE

v_flag BOOLEAN ;

BEGIN

v_flag := true ;

IF v_flag THEN

DBMS_OUTPUT.put_line(‘条件满足。‘) ;

END IF ;

END ;

/

 

范例:定义NUMBER子类型

DECLARE

SUBTYPE score_subtype IS NUMBER(5,2) NOT NULL ;

v_score score_subtype := 99.35 ;

BEGIN

DBMS_OUTPUT.put_line(‘成绩为:‘ || v_score) ;

END ;

/

 

范例:定义VARCHAR2子类型

DECLARE

SUBTYPE string_subtype IS VARCHAR2(200) ;

v_company string_subtype ;

BEGIN

v_company := ‘北京魔乐科技软件学院(www.mldnjava.cn‘ ;

DBMS_OUTPUT.put_line(v_company) ;

END ;

/

 

 

 

**********分支结构***********

 

范例:IF语句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(empno) INTO v_countResult FROM emp ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line(‘EMP表的记录大于10条。‘) ;

END IF ;

END ;

/

 

范例:IF…ELSE语句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(deptno) INTO v_countResult FROM dept ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line(‘DEPT表的记录大于10条。‘) ;

ELSE

DBMS_OUTPUT.put_line(‘DEPT表的记录小于10条。‘) ;

END IF ;

END ;

/

 

范例:IF…ELSIF…ELSE语句

DECLARE

v_countResult NUMBER ;

BEGIN

SELECT COUNT(empno) INTO v_countResult FROM emp ;

IF v_countResult > 10 THEN

DBMS_OUTPUT.put_line(‘EMP表的记录大于10条。‘) ;

ELSIF v_countResult < 10 THEN

DBMS_OUTPUT.put_line(‘EMP表的记录小于10条。‘) ;

ELSE

DBMS_OUTPUT.put_line(‘EMP表的记录等于10条。‘) ;

END IF ;

END ;

/

 

范例:查询emp表的工资,输入员工编号,根据编号查询工资,如果工资高于3000元,则显示高工资,如果工资大于2000元,则显示中等工资,如果工资小于2000元,则显示低工资。

DECLARE

v_empSal emp.sal%TYPE ; -- 定义变量与emp.sal字段类型相同

v_empName emp.ename%TYPE ; -- 定义变量与emp.ename字段类型相同

v_eno emp.empno%TYPE ; -- 定义变量与emp.empno字段类型相同

BEGIN

v_eno := &inputEmpno; -- 用户输入要查找的雇员编号

-- 根据输入的雇员编号查找雇员姓名及工资

SELECT ename,sal INTO v_empName,v_empSal FROM emp WHERE empno=v_eno;

IF v_empSal > 3000 THEN -- 判断

DBMS_OUTPUT.put_line(v_empName || ‘的工资属于高工资!‘) ;

ELSIF v_empSal > 2000 THEN -- 判断

DBMS_OUTPUT.put_line(v_empName || ‘的工资属于中等工资!‘) ;

ELSE

DBMS_OUTPUT.put_line(v_empName || ‘的工资属于低工资!‘) ;

END IF;

END;

/

 

范例:用户输入一个雇员编号,根据它所在的部门给上涨工资,规则:

· 10部门上涨10%20上涨20%30上涨30%

· 但是要求最高不能超过5000,超过5000就停留在5000

DECLARE

v_empSal emp.sal%TYPE ; -- 定义变量与emp.sal字段类型相同

v_dno emp.deptno%TYPE ; -- 定义变量与emp.deptno字段类型相同

v_eno emp.empno%TYPE ; -- 定义变量与emp.empno字段类型相同

BEGIN

v_eno := &inputEmpno; -- 用户输入要查找的雇员编号

SELECT deptno,sal INTO v_dno, v_empSal FROM emp WHERE empno = v_eno ;

IF v_dno = 10 THEN

IF v_empSal * 1.1 > 5000 THEN

UPDATE emp SET sal=5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.1 WHERE empno=v_eno;

END IF;

ELSIF v_dno = 20 THEN

IF v_empSal * 1.2 > 5000 THEN

UPDATE emp SET sal =5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.2 WHERE empno=v_eno;

END IF;

ELSIF v_dno = 30 THEN

IF v_empSal * 1.3 > 5000 THEN

UPDATE emp SET sal=5000 WHERE empno=v_eno;

ELSE

UPDATE emp SET sal=sal*1.3 WHERE empno=v_eno;

END IF;

ELSE

null;

END IF;

END;

/

 

范例:正则验证

DECLARE

v_str VARCHAR2(50) := ‘123‘ ;

BEGIN

IF REGEXP_LIKE(v_str,‘^\d+$‘) THEN

DBMS_OUTPUT.put_line(‘正则验证通过。‘) ;

END IF ;

END ;

/

 

范例:验证AND操作符

BEGIN

IF ‘MLDN‘ = ‘MLDN‘ AND 100 = 100 THEN

DBMS_OUTPUT.put_line(‘结果为TRUE,满足条件!‘) ;

END IF ;

END;

/

 

范例:验证BETWEEN…AND

BEGIN

IF TO_DATE(‘1983-09-19‘,‘yyyy-mm-dd‘) BETWEEN  TO_DATE(‘1980-01-01‘,‘yyyy-mm-dd‘)

AND TO_DATE(‘1989-12-31‘,‘yyyy-mm-dd‘) THEN

DBMS_OUTPUT.put_line(‘您俗称80后!‘) ;

END IF ;

END;

/

 

范例:验证IN操作符

BEGIN

IF 10 IN (10,20,30) THEN

DBMS_OUTPUT.put_line(‘数据已成功查找到‘) ;

END IF ;

END;

/

 

范例:验证IS NULL

DECLARE

v_temp BOOLEAN ; -- 定义布尔变量,没有设置内容

BEGIN

IF v_temp IS NULL THEN

DBMS_OUTPUT.put_line(‘v_temp变量的内容是null‘) ;

END IF ;

END;

/

 

范例:验证LIKE操作符

BEGIN

IF ‘www.mldnjava.cn‘ LIKE ‘%mldn%‘ THEN

DBMS_OUTPUT.put_line(‘可以查找到字符串:mldn‘) ;

END IF ;

END;

/

 

范例:验证NOT操作符

BEGIN

IF NOT FALSE THEN

DBMS_OUTPUT.put_line(‘条件满足,FALSE变为TRUE‘) ;

END IF ;

END;

/

 

范例:

BEGIN

IF ‘MLDN‘ = ‘LXH‘ OR 10 = 10 THEN

DBMS_OUTPUT.put_line(‘有一个条件满足,返回TRUE‘) ;

END IF ;

END;

/

 

范例:使用CASE语句判断数值

DECLARE

v_choose NUMBER := 1 ;

BEGIN

CASE v_choose

WHEN 0 THEN

DBMS_OUTPUT.put_line(‘您选择的是第0项。‘) ;

WHEN 1 THEN

DBMS_OUTPUT.put_line(‘您选择的是第1项。‘) ;

ELSE

DBMS_OUTPUT.put_line(‘没有选项满足。‘) ;

END CASE ;

END ;

/

 

范例:使用CASE进行多条件判断

DECLARE

v_salary emp.sal%TYPE ;

v_eno emp.empno%TYPE ;

BEGIN

v_eno := &inputEmpno ;

SELECT sal INTO v_salary FROM emp WHERE empno=v_eno ;

CASE

WHEN v_salary >= 3000  THEN

DBMS_OUTPUT.put_line(‘雇员:‘ || v_eno || ‘的收入为高工资。‘) ;

WHEN v_salary >= 2000 AND v_salary <3000 THEN

DBMS_OUTPUT.put_line(‘雇员:‘ || v_eno || ‘的收入为中等工资。‘) ;

ELSE

DBMS_OUTPUT.put_line(‘雇员:‘ || v_eno || ‘的收入为低工资。‘) ;

END CASE ;

END ;

/

 

范例:输入雇员编号,根据雇员的职位进行工资提升,提升要求如下

· 如果职位是办事员(CLERK),工资增长5%

· 如果职位是销售人员(SALESMAN),工资增长8%

· 如果职位为经理(MANAGER),工资增长10%

· 如果职位为分析员(ANALYST),工资增长20%

· 如果职位为总裁(PRESIDENT),工资不增长。

DECLARE

v_job emp.job%TYPE ;

v_eno emp.empno%TYPE ;

BEGIN

v_eno := &inputEmpno ;

SELECT job INTO v_job FROM emp WHERE empno=v_eno ;

CASE v_job

WHEN ‘CLERK‘ THEN

UPDATE emp SET sal=sal*1.05 WHERE empno=v_eno ;

WHEN ‘SALESMAN‘ THEN

UPDATE emp SET sal=sal*1.08 WHERE empno=v_eno ;

WHEN ‘MANAGER‘ THEN

UPDATE emp SET sal=sal*1.10 WHERE empno=v_eno ;

WHEN ‘ANALYST‘ THEN

UPDATE emp SET sal=sal*1.20 WHERE empno=v_eno ;

ELSE

DBMS_OUTPUT.put_line(‘雇员:‘ || v_eno || ‘工资不具备上涨资格!‘) ;

END CASE ;

END ;

/

 

范例:使用LOOP循环

EXIT WHEN结束循环

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

LOOP

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

EXIT WHEN v_i >= 3 ;

v_i := v_i + 1 ;

END LOOP ;

END ;

/

 

范例:使用WHILE…LOOP循环

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

WHILE (v_i <= 3) LOOP

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

v_i := v_i + 1 ;

END LOOP ;

END ;

/

 

范例:使用FOR循环

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

FOR v_i IN 1 .. 3 LOOP

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

END LOOP ;

END ;

/

 

范例:使用REVERSE操作

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

FOR v_i IN REVERSE 1 .. 3 LOOP

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

END LOOP ;

END ;

/

 

范例:使用EXIT结束循环操作

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

FOR v_i IN 1 .. 10 LOOP

IF v_i = 3 THEN -- v_i变量增长到3时结束循环

EXIT ;

END IF ;

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

END LOOP ;

END ;

/

 

范例:使用CONTINUE控制循环操作(结束当前的循环)

DECLARE

v_i NUMBER := 1 ; -- 定义一个变量,用于循环

BEGIN

FOR v_i IN 1 .. 10 LOOP

IF MOD(v_i,2) = 0 THEN -- 为偶数的时候不执行后续方法体

CONTINUE ;

END IF ;

DBMS_OUTPUT.put_line(‘v_i = ‘ || v_i) ;

END LOOP ;

END ;

/

 

范例:使用GOTO进行跳转

DECLARE

v_result NUMBER := 1;

BEGIN

FOR v_result IN 1 .. 10 LOOP

IF v_result = 2 THEN

GOTO endPoint ;

END IF ;

DBMS_OUTPUT.put_line(‘v_result = ‘ || v_result) ;

END LOOP ;

<<endPoint>>

DBMS_OUTPUT.put_line(‘FOR循环提前结束。‘) ;

END ;

/

 

范例:定义内部程序块

DECLARE

v_x NUMBER := 30 ; -- 此为全局变量

BEGIN

DECLARE

v_x VARCHAR2(40) := ‘MLDNJAVA‘ ; -- 此为局部变量,只能在内部程序块中使用

v_y NUMBER := 20 ;

BEGIN

DBMS_OUTPUT.put_line(‘内部程序块输出:v_x = ‘ || v_x) ;

DBMS_OUTPUT.put_line(‘内部程序块输出:v_y = ‘ || v_y) ;

END ;

DBMS_OUTPUT.put_line(‘外部程序块输出:v_x = ‘ || v_x) ;

END ;

/

 

范例:程序语法错误

DECLARE

v_result NUMBER := 1 ;

BEGIN

IF v_result = 1-- 此处语法有错误,缺少THEN

DBMS_OUTPUT.put_line(‘条件满足。‘) ;

END IF ;

END ;

/

 

范例:运行时异常

DECLARE

v_result NUMBER ;

BEGIN

v_result := 10/0 ; -- 被除数为0

END ;

/

 

范例:处理被除数为零异常

DECLARE

v_result NUMBER ;

BEGIN

v_result := 10/0 ; -- 被除数为0

DBMS_OUTPUT.put_line(‘异常之后的代码将不再执行!‘) ;

EXCEPTION

WHEN zero_divide THEN

DBMS_OUTPUT.put_line(‘被除数不能为零。‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

END ;

/

 

范例:处理赋值异常

DECLARE

v_varA VARCHAR2(1) ;

v_varB VARCHAR2(4) := ‘java‘ ;

BEGIN

v_varA := v_varB ; -- 错误的赋值

DBMS_OUTPUT.put_line(‘异常之后的代码将不再执行!‘) ;

EXCEPTION

WHEN value_error THEN

DBMS_OUTPUT.put_line(‘数据赋值错误。‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

END ;

/

 

范例:处理SQL异常 —— 找不到数据

DECLARE

v_eno emp.empno%TYPE ;

v_ename emp.ename%TYPE ;

BEGIN

v_eno := &empno ; -- 由键盘输入雇员编号

SELECT ename INTO v_ename FROM emp WHERE empno=v_eno ;

DBMS_OUTPUT.put_line(‘编号为:‘ || v_eno || ‘雇员的名字为:‘ || v_ename) ;

EXCEPTION

WHEN no_data_found THEN

DBMS_OUTPUT.put_line(‘没有这个雇员!‘) ;

END ;

/

 

范例:处理SQL异常 —— 返回多条结果

DECLARE

v_dno emp.deptno%TYPE ;

v_ename emp.ename%TYPE ;

BEGIN

v_dno := &deptno ; -- 由键盘输入部门编号

SELECT ename INTO v_ename FROM emp WHERE deptno=v_dno ;

EXCEPTION

WHEN too_many_rows THEN

DBMS_OUTPUT.put_line(‘返回的数据过多!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

END ;

/

 

范例:使用others来捕获所有异常

DECLARE

v_result NUMBER ;

v_title VARCHAR2(50) := ‘www.mldnjava.cn‘ ;

BEGIN

v_result := v_title ;-- 此处出现异常

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line(‘返回的数据过多!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:使用用户定义异常

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ;

BEGIN

v_data := &inputData ;

IF v_data > 10 AND v_data < 100 THEN

RAISE v_myexp ; -- 抛出异常

END IF ;

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line(‘输入数据有错误!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:设置异常代码

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ;

PRAGMA EXCEPTION_INIT(v_myexp , -20789) ;

BEGIN

v_data := &inputData ;

IF v_data > 10 AND v_data < 100 THEN

RAISE v_myexp ; -- 抛出异常

END IF ;

EXCEPTION

WHEN v_myexp THEN

DBMS_OUTPUT.put_line(‘输入数据有错误!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:绑定已有的错误号

DECLARE

v_myexp EXCEPTION ;

v_input_rowid VARCHAR2(18) ;

PRAGMA EXCEPTION_INIT(v_myexp , -01410) ;

BEGIN

v_input_rowid := ‘&inputRowid‘ ; -- 输入一个ROWID

IF LENGTH(v_input_rowid) <> 18 THEN

RAISE v_myexp ;

END IF ;

EXCEPTION

WHEN v_myexp THEN

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:构建动态异常

DECLARE

v_data NUMBER ;

v_myexpEXCEPTION ; -- 定义了一个异常变量

PRAGMA EXCEPTION_INIT(v_myexp , -20789) ;

BEGIN

v_data := &inputData ; -- 输入数据

IF v_data > 10 AND v_data < 100 THEN

RAISE_APPLICATION_ERROR(-20789 , ‘输入数字不能在10 ~ 100之间!‘) ;

END IF ;

EXCEPTION

WHEN v_myexp THEN -- 出现指定的异常

DBMS_OUTPUT.put_line(‘输入数据有错误!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:不声明异常变量,直接构建异常,同时使用others捕获

DECLARE

v_data NUMBER ;

v_myexp EXCEPTION ; -- 定义了一个异常变量

BEGIN

v_data := &inputData ; -- 输入数据

IF v_data > 10 AND v_data < 100 THEN

RAISE_APPLICATION_ERROR(-20789 , ‘输入数字不能在10 ~ 100之间!‘) ;

END IF ;

EXCEPTION

WHEN others THEN -- 出现指定的异常

DBMS_OUTPUT.put_line(‘输入数据有错误!‘) ;

DBMS_OUTPUT.put_line(‘SQLCODE = ‘ || SQLCODE) ;

DBMS_OUTPUT.put_line(‘SQLERRM = ‘ || SQLERRM) ;

END ;

/

 

范例:使用PL/SQL增加部门信息

DECLARE

v_dno dept.deptno%TYPE ; -- 部门编号

v_dna dept.dname%TYPE ; -- 部门名称

v_dloc dept.loc%TYPE ; -- 部门位置

v_deptCount NUMBER ; -- 保存COUNT()函数结果

BEGIN

v_dno := &inputDeptno ; -- 输入部门编号

v_dna := ‘&inputDname‘ ; -- 输入部门名称

v_dloc := ‘&inputLoc‘ ; -- 接收部门位置

-- 统计要增加的部门编号在dept表中的信息数量,如果返回0表示没有此部门

SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=v_dno ;

IF v_deptCount > 0 THEN -- 部门存在

RAISE_APPLICATION_ERROR(-20888 , ‘此部门编号已存在,请重新输入!‘) ;

ELSE -- 部门不存在

INSERT INTO dept(deptno,dname,loc) VALUES (v_dno,v_dna,v_dloc) ;

DBMS_OUTPUT.put_line(‘新部门增加成功!‘) ;

COMMIT ;

END IF ;

EXCEPTION

WHEN others THEN

DBMS_OUTPUT.put_line(SQLERRM) ;

ROLLBACK ;

END ;

/

PL/SQL编程基础

标签:

原文地址:http://www.cnblogs.com/doudouxiaoye/p/5804055.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!