/*========================================================= PL/SQL編程=========================================================*/--先把scott里面的表弄到test表空間里面來(lái)CREATE TABLE EMP AS SELECT * FROM SCOTT.EMP;CREATE TABLE DEPT AS SELECT * FROM SCOTT.DEPT; /*上機1*/--(1)計算King所交稅金DECLARE V_SHUIJIN NUMBER; --應交稅金 V_SAL SCOTT.EMP.SAL%TYPE; --工資 C_QIZHENDIAN CONSTANT NUMBER :=3500;BEGIN SELECT SAL INTO V_SAL FROM SCOTT.EMP WHERE ENAME='KING'; IF (V_SAL-C_QIZHENDIAN)<=1500 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.03-0; ELSIF (V_SAL-C_QIZHENDIAN)>1500 AND (V_SAL-C_QIZHENDIAN)<=4500 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.1-105; ELSIF (V_SAL-C_QIZHENDIAN)>4500 AND (V_SAL-C_QIZHENDIAN)<=9000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.2-555; ELSIF (V_SAL-C_QIZHENDIAN)>9000 AND (V_SAL-C_QIZHENDIAN)<=35000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.25-1005; ELSIF (V_SAL-C_QIZHENDIAN)>35000 AND (V_SAL-C_QIZHENDIAN)<=55000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.3-2755; ELSIF (V_SAL-C_QIZHENDIAN)>55000 AND (V_SAL-C_QIZHENDIAN)<=80000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.35-5505; ELSIF (V_SAL-C_QIZHENDIAN)>80000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.45-13505; END IF; DBMS_OUTPUT.PUT_LINE('KING所交的稅金是:'||V_SHUIJIN);END;--(2)根據員工scott入職的時(shí)間修改發(fā)放獎金列,大于等于6年的獎金為2000,小于6年的獎金是1500DECLARE V_SCOTT_HIREDATE EMP.HIREDATE%TYPE; --SCOTT的入職時(shí)間 V_COMM NUMBER; --獎金 BEGIN SELECT HIREDATE INTO V_SCOTT_HIREDATE FROM EMP WHERE ENAME='SCOTT'; IF (SYSDATE-V_SCOTT_HIREDATE)>=365*6 THEN V_COMM:=2000; ELSE V_COMM:=1500; END IF; --開(kāi)始修改 UPDATE EMP SET COMM=V_COMM WHERE ENAME='SCOTT'; IF SQL%ROWCOUNT>0 THEN DBMS_OUTPUT.PUT_LINE('修改成功!'); ELSE DBMS_OUTPUT.PUT_LINE('修改失??!'); END IF;END;--(3)查詢(xún)scott相應的工資級別并顯示所在部門(mén)名稱(chēng),薪水,和所在的級別DECLARE V_SCOTT_SAL EMP.SAL%TYPE; --scott的工資 V_JIBIE NUMBER; --級別 V_DEPTNAME DEPT.DNAME%TYPE; --部門(mén)名稱(chēng) BEGIN SELECT SAL,DNAME INTO V_SCOTT_SAL,V_DEPTNAME FROM EMP E JOIN DEPT D ON E.DEPTNO=D.DEPTNO WHERE ENAME='SCOTT'; IF V_SCOTT_SAL>700 AND V_SCOTT_SAL<=3200 THEN V_JIBIE:=1; --第一級別 ELSIF V_SCOTT_SAL>3200 AND V_SCOTT_SAL<=4400 THEN V_JIBIE:=2; --第二級別 ELSIF V_SCOTT_SAL>4400 AND V_SCOTT_SAL<=5000 THEN V_JIBIE:=3; --第三級別 ELSIF V_SCOTT_SAL>5000 AND V_SCOTT_SAL<=7000 THEN V_JIBIE:=4; --第四級別 ELSIF V_SCOTT_SAL>7000 AND V_SCOTT_SAL<=10000 THEN V_JIBIE:=5; --第五級別 END IF; DBMS_OUTPUT.PUT_LINE('SCOTT所在的部門(mén)是:'||http://www.1aqp.com||',薪水是:'||V_SCOTT_SAL||',所在的級別是:第'||V_JIBIE||'級別');END; --(4)位員工scott增加工資,每次增加100,直到增加到10000為止DECLARE V_SCOTT_SAL EMP.SAL%TYPE; --SCOTT的工資BEGIN SELECT SAL INTO V_SCOTT_SAL FROM EMP WHERE ENAME='SCOTT'; LOOP --增加工資 V_SCOTT_SAL:=V_SCOTT_SAL+100; EXIT WHEN V_SCOTT_SAL>=10000; END LOOP; --修改scott的工資 UPDATE EMP SET SAL=V_SCOTT_SAL WHERE ENAME='SCOTT'; IF SQL%ROWCOUNT>0 THEN DBMS_OUTPUT.PUT_LINE('增加成功!'); ELSE DBMS_OUTPUT.PUT_LINE('增加失??!'); END IF;END; /*上機2 預定義異常公司通過(guò)emp表維護職員記錄,用以接收職員編號并檢索職員姓名,*/ DECLARE V_ENAME VARCHAR2(4);BEGIN SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO=&EMPNO; DBMS_OUTPUT.PUT_LINE('已找到'||V_ENAME);EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('對不起,沒(méi)有該職員!'); WHEN VALUE_ERROR THEN DBMS_OUTPUT.PUT_LINE('職員名稱(chēng)太長(cháng)!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('出現其他的異常!');END;/*上機3自定義異常、||輸入員工編號,工資,部門(mén)編號,||如果部門(mén)代碼是10,且工資低于10000,更新員工的工資是10000||如果部門(mén)代碼是10,工資高于10000,顯示消息“工資不低于10000”||如果部門(mén)代碼不是10則不顯示*/DECLARE V_EMPNO EMP.EMPNO%TYPE; --員工編號 V_DEPTNO EMP.DEPTNO%TYPE; --部門(mén)編號 V_SAL EMP.SAL%TYPE; --工資 V_ENAME EMP.ENAME%TYPE; --姓名 V_V_EMPNO EMP.EMPNO%TYPE; --輸入員工編號 V_V_DEPTNO EMP.DEPTNO%TYPE; --輸入部門(mén)編號 V_V_SAL EMP.SAL%TYPE; --輸入工資 E_ERROR_DEPTNO EXCEPTION; --自定義異常(部門(mén)編號不是10) E_ERROR_EMPNO EXCEPTION; --自定義異常(找不到該員工) V_COUNT NUMBER; --聲明一個(gè)記錄數BEGIN --輸入員工編號 V_EMPNO:=&V_V_EMPNO; --輸入工資 V_SAL:=&V_VSAL; --輸入部門(mén)編號 V_DEPTNO:=&V_V_DEPTNO; IF V_DEPTNO=10 THEN --在進(jìn)行二次判斷(輸入員工編號) IF V_SAL<10000 THEN --判斷輸入的員工編號是否存在,不存在的話(huà)報異常,存在的話(huà)繼續 SELECT COUNT(*) INTO V_COUNT FROM EMP WHERE EMPNO=V_DEPTNO; IF V_COUNT!=1 THEN RAISE E_ERROR_EMPNO; --報異常 ELSE --更新工資為1000 UPDATE EMP SET SAL=10000 WHERE EMPNO=V_EMPNO; IF SQL%ROWCOUNT>0 THEN DBMS_OUTPUT.PUT_LINE('更新成功!!!'); ELSE DBMS_OUTPUT.PUT_LINE('更新失敗!!!'); END IF; END IF; ELSIF V_SAL>10000 THEN DBMS_OUTPUT.PUT_LINE('工資不低于10000!!'); END IF; ELSE RAISE E_ERROR_DEPTNO; END IF;EXCEPTION WHEN E_ERROR_DEPTNO THEN DBMS_OUTPUT.PUT_LINE('部門(mén)代碼不是10??!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('出現其他異常,請自行解決?。?!');END;------------------------------------------------------SELECT * FROM EMP;DECLARE V_NAME EMP.ENAME%TYPE; E_ERROR EXCEPTION; V_COUNT NUMBER; --記錄數BEGIN SELECT COUNT(*) INTO V_COUNT FROM EMP WHERE EMPNO=7901; IF (V_COUNT=1) THEN DBMS_OUTPUT.PUT_LINE(V_NAME); ELSE RAISE E_ERROR; END IF; EXCEPTION WHEN E_ERROR THEN DBMS_OUTPUT.PUT_LINE('沒(méi)有記錄!'); /*when no_data_found then DBMS_OUTPUT.PUT_LINE('找不到!');*/ END;-------------------------------------------------------------DECLARE V_NAME VARCHAR2(10); E_ERROR EXCEPTION;BEGIN IF V_NAME IS NULL THEN RAISE E_ERROR; ELSE DBMS_OUTPUT.PUT_LINE(http://www.7aqp.com); END IF; EXCEPTION WHEN E_ERROR THEN DBMS_OUTPUT.PUT_LINE('沒(méi)有記錄!'); END;/*//上機4使用游標*/--(1)計算公司應交稅金的總額DECLARE V_SHUIJIN NUMBER; --應交稅金 V_SAL SCOTT.EMP.SAL%TYPE; --工資 V_SUM NUMBER(10):=0; --總稅金 C_QIZHENDIAN CONSTANT NUMBER :=3500; CURSOR CURSOR_SAL IS SELECT SAL FROM EMP; --所有的員工的工資BEGIN OPEN CURSOR_SAL; LOOP FETCH CURSOR_SAL INTO V_SAL;--把所有的工資放在V_SAL里面 EXIT WHEN CURSOR_SAL%NOTFOUND; IF (V_SAL-C_QIZHENDIAN)<=1500 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.03-0; ELSIF (V_SAL-C_QIZHENDIAN)>1500 AND (V_SAL-C_QIZHENDIAN)<=4500 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.1-105; ELSIF (V_SAL-C_QIZHENDIAN)>4500 AND (V_SAL-C_QIZHENDIAN)<=9000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.2-555; ELSIF (V_SAL-C_QIZHENDIAN)>9000 AND (V_SAL-C_QIZHENDIAN)<=35000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.25-1005; ELSIF (V_SAL-C_QIZHENDIAN)>35000 AND (V_SAL-C_QIZHENDIAN)<=55000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.3-2755; ELSIF (V_SAL-C_QIZHENDIAN)>55000 AND (V_SAL-C_QIZHENDIAN)<=80000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.35-5505; ELSIF (V_SAL-C_QIZHENDIAN)>80000 THEN V_SHUIJIN:=(V_SAL-C_QIZHENDIAN)*0.45-13505; END IF; V_SUM:=V_SUM+V_SHUIJIN; END LOOP; CLOSE CURSOR_SAL; --關(guān)閉游標 DBMS_OUTPUT.PUT_LINE(V_SUM);EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('出現異常!');END; --(2)根據員工入職時(shí)間修改所有員工發(fā)放獎金,大于6年的+2000,小于的1500+DECLARE V_COMM EMP.COMM%TYPE; --獎金 CURSOR CURSOR_EMP_COMM IS SELECT HIREDATE FROM EMP FOR UPDATE; BEGIN FOR CUR1 IN CURSOR_EMP_COMM LOOP IF (SYSDATE-CUR1.HIREDATE)>=365*6 THEN V_COMM:=2000; ELSE V_COMM:=1500; END IF; --開(kāi)始修改 UPDATE EMP SET COMM=V_COMM WHERE CURRENT OF CURSOR_EMP_COMM; IF SQL%ROWCOUNT>0 THEN DBMS_OUTPUT.PUT_LINE('更新成功!!!'); ELSE DBMS_OUTPUT.PUT_LINE('更新失敗!!!'); END IF; END LOOP;EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('出現異常!');END;--(3)顯示員工姓名,所在部門(mén)名稱(chēng),薪水,所在級別DECLARE C_DNAME CONSTANT VARCHAR2(20):='SALES'; --銷(xiāo)售部門(mén) V_JIBIE NUMBER; --級別 CURSOR CURSOR_EMP IS SELECT ENAME,DNAME,SAL FROM EMP E JOIN DEPT D ON E.DEPTNO=D.DEPTNO WHERE DNAME=C_DNAME; BEGIN FOR C1 IN CURSOR_EMP LOOP IF C1.SAL>700 AND C1.SAL<=3200 THEN V_JIBIE:=1; --第一級別 ELSIF C1.SAL>3200 AND C1.SAL<=4400 THEN V_JIBIE:=2; --第二級別 ELSIF C1.SAL>4400 AND C1.SAL<=5000 THEN V_JIBIE:=3; --第三級別 ELSIF C1.SAL>5000 AND C1.SAL<=7000 THEN V_JIBIE:=4; --第四級別 ELSIF C1.SAL>7000 AND C1.SAL<=10000 THEN V_JIBIE:=5; --第五級別 ELSE V_JIBIE:=0; --沒(méi)有級別 END IF; DBMS_OUTPUT.put_line(C1.ENAME||'在'||C1.DNAME||'部門(mén),'||'薪水是'||C1.SAL||'在第'||V_JIBIE||'級別'); END LOOP;EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('出現異常!');END;/*上機5 存儲過(guò)程*/--(1)根據輸入的員工編號,刪除相應的員工CREATE OR REPLACE PROCEDURE DEL_EMPNAME( ENO EMP.EMPNO%TYPE, --輸入員工的編號 ON_FLAG OUT NUMBER, --執行狀態(tài),-1失敗,1成功 0異常 ON_MSG OUT VARCHAR --提示信息 )IS E_ERROR EXCEPTION; --異常信息BEGIN DELETE FROM EMP WHERE EMPNO=ENO; IF SQL%NOTFOUND THEN RAISE E_ERROR; ELSE ON_FLAG:=1; --執行成功 ON_MSG:='刪除成功!'; END IF;EXCEPTION WHEN E_ERROR THEN ON_FLAG:=0; --執行成功 ON_MSG:='刪除失??!'; WHEN OTHERS THEN ON_FLAG:=0; ON_MSG:='出現異常!';END;DROP PROCEDURE DEL_EMPNAME;--調用存儲過(guò)程DECLARE V_EMPNO NUMBER; ENO NUMBER(5); ON_FLAG NUMBER(1); ON_MSG VARCHAR(20);BEGIN ENO:=&EMPNO; --輸入編號 DEL_EMPNAME(ENO,ON_FLAG,ON_MSG); DBMS_OUTPUT.PUT_LINE(ON_FLAG); DBMS_OUTPUT.PUT_LINE(ON_MSG);END;--(2)創(chuàng )建輸出參數為薪水集合的存儲過(guò)程,調用并顯示所有員工的薪水聯(lián)系客服