1 第一个PL/SQL的程序
DECLARE BEGIN DBMS_OUTPUT.PUT_LINE('Hello World!'); END; /
--2一个简单的PL/SQL程序
DECLARE v_num NUMBER; BEGIN v_num:=30; dbms_output.put_line('v_num变量内容是:'||v_num); END; /
--3输入 一个员工编号,而后取得员工姓名
DECLARE v_eno NUMBER:=&ID; v_ename VARCHAR2(20); BEGIN SELECT ename INTO v_ename FROM emp WHERE empno=v_eno; dbms_output.put_line('编号为:'||v_eno||' 员工姓名:'||v_ename); END; /
--变量的声明与赋值%type和%rowtype的使用
--定义变量不设置默认值
DECLARE v_result VARCHAR2(30); --只声明变量没有内容 BEGIN dbms_output.put_line('v_result的内容:'||v_result ); END; /
--5加法
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; --只声明变量没有内容 BEGIN dbms_output.put_line('v_resultA:'||v_resultA ); END; /
--定义非空
DECLARE v_resultA NUMBER NOT NULL; --只声明变量没有内容 BEGIN dbms_output.put_line('v_resultA:'||v_resultA ); END; /
--定义常量
DECLARE v_resultA CONSTANT NUMBER NOT NULL:=100; --使用CONSTANT关键字定义常量 BEGIN dbms_output.put_line('v_resultA:'||v_resultA ); END; /
--常量不能改变
DECLARE v_resultA CONSTANT NUMBER NOT NULL:=100; --使用CONSTANT关键字定义常量 BEGIN v_resultA:=20; dbms_output.put_line('v_resultA:'||v_resultA ); END; /
--如果希望与指定数据表中某一列的类型一样,则可以使用 变量名 表名称。字段名称%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 标记定义表中一行的记录类型
--使用ROWTYPE装载一行记录
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 v_info VARCHAR2(50):='欢迎使用Oracle数据库'; vurl VARCHAR2(50); BEGIN vurl :='www.163.com'; dbms_output.put_line(v_info); dbms_output.put_line(v_url); END; /
连接运算符
使用”||”完成操作
DECLARE v_info VARCHAR2(50):='欢迎使用Oracle数据库'; v_url VARCHAR2(50); BEGIN v_url :='www.163.com'; dbms_output.put_line(v_info ||'网址'|| v_url); END; /
--关系运算符
--关系运算符>,<,>=,<=,=,!=,<>
--判断NULL IS NULL ,IS NOT NULL
--范围查询 BETWEEN 最小值 AND最大值
--范围查询 IN
--模糊查询LIKE
DECLARE v_url VARCHAR2(50):='www.163.com'; v_num1 NUMBER:=80; v_num2 NUMBER:=30; BEGIN IF v_num1>v_num2 THEN dbms_output.put_line('第一个数字比第二个数字大'); END IF; IF v_url LIKE '%163%' THEN dbms_output.put_line('网址中包含163的字样'); END IF; END; /
--逻辑运算符 AND RO NOT
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_flage1 AND (NOT v_flag2)=TRUE'); END IF; IF v_flag1 OR v_flag3 THEN dbms_output.put_line('v_flage1 OR v_flag3=TRUE'); END IF; IF v_flag1 AND v_flag3 IS NULL THEN dbms_output.put_line('v_flage1 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_x'|| (v_x+v_y)); END; /
--BINARY_INTEGER与 PLS_INTEGER(-2147483648---2147483647)
--BINARY_INTEGER与 PLS_INTEGER具有相同的范围长度,与NUMBER相比较其所占用的范围更小,
--在数学计算时,NUMBER保存为十进制,需要先转换为二进制后才可以说进行计算,
----BINARY_INTEGER与 PLS_INTEGER采用二进制的补码形式存储,所以性能上要比NUMBER高
--但是--BINARY_INTEGER与 PLS_INTEGER还是有区别的
--当--BINARY_INTEGER操作的数大于其数据范围里会变为NUMBER,
--PLS_INTEGER操作的数大于其数据范围里会抛出异常
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;
--字符型
--char和VARCHAR2
DECLARE v_info_char CHAR(10); v_info_varchar VARCHAR2(10); BEGIN v_info_char:='bdqn'; v_info_varchar:='java'; dbms_output.put_line('v_info_char内容长度:'||LENGTH(v_info_char)); dbms_output.put_line('v_info_varchar内容长度:'||LENGTH(v_info_varchar)); END;
--Nchar和NVARCHAR2
DECLARE v_info_char NCHAR(10); v_info_varchar NVARCHAR2(10); BEGIN v_info_char:='bdqn'; v_info_varchar:='java'; dbms_output.put_line('v_info_char内容长度:'||LENGTH(v_info_char)); dbms_output.put_line('v_info_varchar内容长度:'||LENGTH(v_info_varchar)); END;
NCHAR和NVARCHAR2保存数据为UNICODE编码,中文或者英文都会变为十六进制保存,但是浪费空间
--日期型
--date数据
--定义DATE型变量
DECLARE v_date1 DATE:=SYSDATE; v_date2 DATE:=SYSTIMESTAMP; v_date3 DATE:='23-9月-1984'; 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_date1 TIMESTAMP:=SYSDATE; v_date2 TIMESTAMP:=SYSTIMESTAMP; v_date3 TIMESTAMP:='23-9月-1984'; BEGIN dbms_output.put_line('日期数据 :'|| v_date1); dbms_output.put_line('日期数据 :'|| v_date2); dbms_output.put_line('日期数据 :'|| v_date3); END;
-- --if
DECLARE v_countResult NUMBER; BEGIN SELECT COUNT(*) 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(*) 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(*) 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_ENO EMP.EMPNO%TYPE; V_EMPSAL EMP.SAL%TYPE; V_EMPNAME EMP.ENAME%TYPE; BEGIN V_ENO := &EMPNO; 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_id emp.empno%TYPE:=&empno; --用户输入编号 v_deptno emp.deptno%TYPE; --变量部门编号 v_sal emp.sal%TYPE ; --变量工资 BEGIN SELECT deptno ,sal INTO v_deptno,v_sal FROM emp WHERE empno=v_id; IF v_deptno=10 THEN IF v_sal*1.1>5000 THEN dbms_output.put_line(v_id||'涨工资后'|| 5000||'元'); ELSE dbms_output.put_line(v_id||'涨工资后'||v_sal*1.1); END IF; ELSIF v_deptno=20 THEN IF v_sal*1.2>5000 THEN dbms_output.put_line(v_id||'涨工资后'|| 5000||'元'); ELSE dbms_output.put_line(v_id||'涨工资后'||v_sal*1.2); END IF; ELSIF v_deptno=30 THEN IF v_sal*1.3>5000 THEN dbms_output.put_line(v_id||'涨工资后'|| 5000||'元'); ELSE dbms_output.put_line(v_id||'涨工资后'||v_sal*1.3); END IF; ELSE NULL; END IF; END;
--循环
--loop循环
DECLARE v_i NUMBER:=1; BEGIN LOOP dbms_output.put_line(v_i); v_i:=v_i+1; EXIT WHEN v_i>8; END LOOP; END;
--WHILE..loop
DECLARE v_i NUMBER:=1; BEGIN WHILE v_i<15 LOOP dbms_output.put_line(v_i); v_i:=v_i+1; END LOOP; END;
---for 循环
DECLARE v_i NUMBER; BEGIN FOR v_i IN 1..18 LOOP dbms_output.put_line(v_i); END LOOP; END;
--使用REVERSE递减
DECLARE v_i NUMBER; BEGIN FOR v_i IN REVERSE 1..18 LOOP dbms_output.put_line(v_i); END LOOP; END;
--循环控制
--使用EXIT退出
DECLARE v_i NUMBER; BEGIN FOR v_i IN 1..10 LOOP IF v_i=6 THEN EXIT; END IF; dbms_output.put_line(v_i); END LOOP; END;
--使用contiune结束当次循环
DECLARE v_i NUMBER; BEGIN FOR v_i IN 1..10 LOOP IF mod(v_i,2)=0 THEN CONTINUE; END IF; dbms_output.put_line(v_i); END LOOP; END;
---嵌套语法
DECLARE
声明部分
BEGIN
程序执行部分,
DECLARE
声明部分
BEGIN
程序执行部分,
EXECPTION
异常处理部分
END;
EXECPTION
异常处理部分
END;
--定义内部程序块
DECLARE v_x NUMBER:=30; BEGIN DECLARE v_x VARCHAR2(40):='JAVA 学习'; 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_dno dept.deptno%TYPE:=&deptno; --部门编号 v_dna dept.dname%TYPE:='&dname'; ---部门名称 v_dloc dept.loc%TYPE:='&loc'; -- 部门位置 v_deptCount NUMBER; --保存count()函数的结果 BEGIN 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;