PL/SQL基础

一.入门

1.打印helloworld
DECLARE --说明部分
BEGIN
dbms_output.put_line ('Hello,world') ;
END ;

二.变量

2.引用型变量,查询并打印7835的姓名和薪水
DECLARE --定义变量保存姓名和薪水
pname emp.ename % TYPE ; psal emp.sal % TYPE ;
BEGIN
--得到员工的姓名和薪水
SELECT ename,sal
INTO pname,psal
FROM emp
WHERE
empno = 7839 ;
dbms_output.put_line (pname || '的薪水是' || psal) ;
END ;

3.记录型变量

DECLARE emp_rec emp % rowtype ;
BEGIN
    SELECT
        * INTO emp_rec
    FROM
        emp
    WHERE
        empno = 7839 ; dbms_output.put_line (
            emp_rec.ename || '的薪水是' || emp_rec.sal
        ) ;
    END ;

三.条件与循环

 4.条件判断

DECLARE pnum NUMBER := 1 ;
BEGIN

IF pnum = 0 THEN
    dbms_output.put_line (
        '您输入的数字是0'
    ) ;

ELSIF pnum = 1 THEN
    dbms_output.put_line (
        '您输入的数字是1'
    ) ;
ELSE
    dbms_output.put_line ('其它数字') ;
END IF;
END ;

5.while循环
DECLARE pnum NUMBER := 1 ;
BEGIN
    LOOP
        --退出循环条件
        EXIT WHEN pnum > 10;
        dbms_output.put_line (pnum) ;
        pnum := pnum + 1;
    END LOOP;
END ;

.光标

6.光标的属性

1)%isopen 是否被打开 

2)%rowcount(影响的行数) 

3)%found有记录

4)%notfound没有记录

7.查询并打印员工的姓名和薪水

DECLARE
    --定义光标
    CURSOR cemp is SELECT ename,sal FROM emp;
    pname emp.ename%TYPE;
    psal  emp.sal%TYPE;
BEGIN
    --打开光标
    OPEN cemp;
    LOOP
            --取出当前记录
            FETCH cemp INTO pname,psal;
            EXIT WHEN cemp%notfound;
            dbms_output.put_line(pname||'的薪水是'||psal);
    END LOOP;
    CLOSE cemp;
END ;

8.给员工涨工资

DECLARE
    --定义光标
    CURSOR cemp IS SELECT empno,job FROM emp;
    pempno emp.empno%TYPE;
    pjob emp.job%TYPE;
BEGIN
    --打开光标
    OPEN cemp;
    LOOP
            --取一个员工
            FETCH cemp INTO pempno,pjob;
            EXIT WHEN cemp%NOTFOUND;
            IF
                pjob = 'PRESIDENT' THEN UPDATE emp SET sal = sal+1000 WHERE empno=pempno;
            ELSIF pjob = 'MANAGER' THEN UPDATE emp SET sal = sal+800 WHERE empno=pempno;
            ELSE UPDATE emp SET sal = sal+400 WHERE empno=pempno;
            END IF;
    END LOOP;
    --关闭光标
    CLOSE cemp;
    --提交
    COMMIT;
    dbms_output.put_line('完成');
END;

9.形参和实参

DECLARE
    --形参
    CURSOR cemp(dno NUMBER) IS SELECT ename FROM emp WHERE deptno=dno;
    pename emp.ename%TYPE;
BEGIN
    --实参
    OPEN cemp(10);
    LOOP
            FETCH cemp INTO pename;
            EXIT WHEN cemp%NOTFOUND;
            dbms_output.put_line(pename);
    END LOOP;
    CLOSE cemp;
END;

五.例外

10.被0除异常

DECLARE

    pnum NUMBER;
BEGIN
        pnum := 1/0;
EXCEPTION
        WHEN ZERO_DIVIDE THEN dbms_output.put_line('1:0不能做分母');
                                                    dbms_output.put_line('2:0不能做分母');
        WHEN VALUE_ERROR THEN dbms_output.put_line('算术或者转换错误');
        WHEN OTHERS THEN dbms_output.put_line('其它例外');
END;

11.自定义异常

DECLARE
    CURSOR cemp IS SELECT ename FROM emp WHERE deptno = 50;
        pename emp.ename%TYPE;
        --自定义意外
        no_emp_found EXCEPTION;
BEGIN
        OPEN cemp;
        --取第一条记录
        FETCH cemp INTO pename;
        IF cemp%NOTFOUND THEN
            --抛出异常
            RAISE no_emp_found;
        END IF;    
        CLOSE cemp;
EXCEPTION
        WHEN no_emp_found THEN dbms_output.put_line('没有找到员工');
        WHEN OTHERS THEN dbms_output.put_line('其它例外');
END;

.实例

1.统计每年入职员工的个数

DECLARE
--定义光标
    CURSOR cemp IS SELECT TO_ChAR(hiredate,'yyyy') FROM emp;
    phiredate VARCHAR2(4);

    count80 NUMBER := 0;
    count81 NUMBER := 0;
    count82 NUMBER := 0;
    count87 NUMBER := 0;
BEGIN
    --打开光标
    OPEN cemp;
    LOOP
        --取一个员工的入职年份
        FETCH cemp INTO phiredate;
        EXIT WHEN cemp%NOTFOUND;
        IF phiredate = '1980' THEN count80 := count80+1;
            ELSIF phiredate = '1981' THEN count81 := count81+1;
            ELSIF phiredate = '1982' THEN count82 := count82+1;
            ELSE count87 := count87+1;
        END IF;
    END LOOP;
    --关闭光标
    CLOSE cemp;
    dbms_output.put_line('Total:'||(count80+count81+count82+count87));
    dbms_output.put_line('1980:'||count80);
    dbms_output.put_line('1981:'||count81);
    dbms_output.put_line('1982:'||count82);
    dbms_output.put_line('1987:'||count87);
END;

2.涨工资

DECLARE
--定义光标
    CURSOR cemp IS SELECT empno,sal FROM emp ORDER BY sal;
    pempno emp.empno%TYPE;
    psal emp.sal%TYPE;
    
--涨工资的人数
    countEmp NUMBER := 0;
--涨后的工资总额
    salTotal NUMBER;
BEGIN
    --得到工资的初始值
    SELECT sum(sal) INTO salTotal FROM emp;
    --打开光标
    OPEN cemp;
    IF salTotal < 70000 THEN
        LOOP
            --涨工资总额大于7万
            EXIT WHEN salTotal > 70000;
        
            --取一个员工
            FETCH cemp INTO pempno,psal;
            --notfound
            EXIT WHEN cemp%NOTFOUND;
            --涨工资
            UPDATE emp SET sal = sal * 1.1 WHERE empno = pempno;
            --人数+1
            countEmp := countEmp + 1;
            --涨后的工资总额
            salTotal := salTotal + psal*0.1;
            
        END LOOP;
    END IF;
    --关闭光标
    CLOSE cemp;
    COMMIT;
    dbms_output.put_line('人数:'||countEmp);
    dbms_output.put_line('总额度:'||salTotal);
END;

原文地址:https://www.cnblogs.com/wangxiayun/p/9025746.html