oracle筆記pl/sql流程控制
阿新 • • 發佈:2018-12-19
/* pl/sql流程控制 */ /* 查詢出 150號 員工的工資, 若其工資大於或等於 10000 則列印 'salary >= 10000'; 若在 5000 到 10000 之間, 則列印 '5000<= salary < 10000'; 否則列印 'salary < 5000' */ DECLARE v_salary employees.salary%TYPE; BEGIN SELECT salary INTO v_salary FROM employees WHERE employee_id = 150; dbms_output.put_line('150號員工的薪水為' || v_salary); IF v_salary >= 10000 THEN dbms_output.put_line('salary >= 10000'); ELSIF v_salary >= 5000 THEN dbms_output.put_line('5000<= salary < 10000'); ELSE dbms_output.put_line('salary < 5000'); END IF; --END IF;相當於java中的結束大括號,pl/sql中使用END IF關鍵字充當結束大括號 END; -- DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); IF v_salary >= 10000 THEN dbms_output.put_line('salary >= 10000'); ELSIF v_salary >= 5000 THEN dbms_output.put_line('5000<= salary < 10000'); ELSE dbms_output.put_line('salary < 5000'); END IF; --END IF;相當於java中的結束大括號,pl/sql中使用END IF關鍵字充當結束大括號 END; --另外一種寫法 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); IF v_salary >= 10000 THEN v_temp := 'salary >= 10000'; ELSIF v_salary >= 5000 THEN v_temp := '5000<= salary < 10000'; ELSE v_temp := 'salary < 5000'; END IF; --END IF;相當於java中的結束大括號,pl/sql中使用END IF關鍵字充當結束大括號 dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; --改成case的寫法 /* --以下這種寫法是錯誤的,會報錯 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := CASE v_salary WHEN v_salary >= 10000 THEN 'salary >= 10000' WHEN v_salary >= 5000 THEN '5000<= salary < 10000' ELSE 'salary < 5000' END; dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; */ --以下寫法正確 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := CASE WHEN v_salary >= 10000 THEN 'salary >= 10000' WHEN v_salary >= 5000 THEN '5000<= salary < 10000' ELSE 'salary < 5000' END; dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; /* --以下這種寫法是錯誤的,會報錯 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); (CASE WHEN v_salary >= 10000 THEN v_temp := 'salary >= 10000' WHEN v_salary >= 5000 THEN v_temp := '5000<= salary < 10000' ELSE v_temp := 'salary < 5000' END); dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; --以下這種寫法是錯誤的,會報錯 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); CASE WHEN v_salary >= 10000 THEN v_temp := 'salary >= 10000' WHEN v_salary >= 5000 THEN v_temp := '5000<= salary < 10000' ELSE v_temp := 'salary < 5000' END; dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; */ --以下寫法正確 DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := (CASE WHEN v_salary >= 10000 THEN 'salary >= 10000' WHEN v_salary >= 5000 THEN '5000<= salary < 10000' ELSE 'salary < 5000' END); dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; -- DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := CASE trunc(v_salary / 5000) WHEN 0 THEN 'salary < 5000' WHEN 1 THEN '5000<= salary < 10000' ELSE 'salary >= 10000' END; dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; -- DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := CASE WHEN v_salary >= 10000 THEN 'salary >= 10000' WHEN v_salary >= 5000 THEN '5000<= salary < 10000' ELSE 'salary < 5000' END; dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; -- DECLARE v_salary employees.salary%TYPE; v_employee_id employees.employee_id%TYPE; v_temp VARCHAR2(50); BEGIN v_employee_id := 150; --給v_employee_id變數賦值 SELECT salary INTO v_salary FROM employees WHERE employee_id = v_employee_id; --使用v_employee_id變數 dbms_output.put_line(v_employee_id || '號員工的薪水=' || v_salary); v_temp := (CASE WHEN v_salary >= 10000 THEN 'salary >= 10000' WHEN v_salary >= 5000 THEN '5000<= salary < 10000' ELSE 'salary < 5000' END); dbms_output.put_line('薪水=' || v_salary || ',' || v_temp); END; /* 以前的知識回顧 */ --以下這2種寫法都可以 -- SELECT (CASE department_id WHEN 80 THEN '80號部門' WHEN 90 THEN '90號部門' END) FROM employees -- SELECT (CASE WHEN department_id = 80 THEN '80號部門' WHEN department_id = 90 THEN '90號部門' END) FROM employees -- SELECT job_id FROM employees /* 回顧知識點 CASE... WHEN... THEN... WHEN... THEN... ELSE... END */ --以下寫法正確 SELECT (CASE job_id WHEN 'IT_PROG' THEN 'IT崗位' WHEN 'SA_REP' THEN '銷售崗位' END) FROM employees --以下寫法錯誤,會報錯 SELECT (CASE salary WHEN salary >= 5000 THEN '薪水大於5000' WHEN salary < 5000 THEN '薪水小於5000' END) FROM employees --以下寫法正確 SELECT (CASE WHEN salary >= 5000 THEN '薪水大於5000' WHEN salary < 5000 THEN '薪水小於5000' END) FROM employees --以下寫法錯誤 SELECT (CASE WHEN salary >= 5000 THEN salary = 10 WHEN salary < 5000 THEN salary = 20 END) FROM employees --以下寫法正確 SELECT (CASE salary WHEN 24000 THEN '薪水等於24000' WHEN 8000 THEN '薪水等於8000' END) FROM employees --以下寫法正確 SELECT (CASE salary WHEN 24000 THEN '薪水等於24000' WHEN 8000 THEN '薪水等於8000' ELSE 'hello world' END) FROM employees --以下寫法正確 SELECT salary, (CASE salary WHEN 24000 THEN salary + 10 WHEN 8000 THEN salary + 20 ELSE salary + 30 END) FROM employees --以下寫法錯誤,會報錯 SELECT salary, (CASE salary WHEN 24000 THEN salary = salary + 10 WHEN 8000 THEN salary = salary + 20 ELSE salary = salary + 30 END) FROM employees --以下寫法錯誤,會報錯 SELECT salary, (CASE salary WHEN 24000 THEN salary = 10 WHEN 8000 THEN salary = 20 ELSE salary = 30 END) FROM employees SELECT * FROM employees ----------------------------------------- /* 查詢出 122 號員工的 JOB_ID, 若其值為 'IT_PROG', 則列印 'GRADE: A'; 'AC_MGT', 列印 'GRADE B', 'AC_ACCOUNT', 列印 'GRADE C'; 否則列印 'GRADE D' */ --使用if ELSIF DECLARE v_job_id employees.job_id%TYPE; v_grade VARCHAR2(50); BEGIN SELECT job_id INTO v_job_id FROM employees WHERE employee_id = 122; IF v_job_id = 'IT_PROG' THEN v_grade := 'GRADE: A'; ELSIF v_job_id = 'AC_MGT' THEN v_grade := 'GRADE: B'; ELSIF v_job_id = 'AC_ACCOUNT' THEN v_grade := 'GRADE: C'; ELSE v_grade := 'GRADE: D'; END IF; dbms_output.put_line(v_job_id || ' ,grade = ' || v_grade); END; --使用CASE WHEN THEN DECLARE v_job_id employees.job_id%TYPE; v_grade VARCHAR2(50); BEGIN SELECT job_id INTO v_job_id FROM employees WHERE employee_id = 122; v_grade := CASE v_job_id WHEN 'IT_PROG' THEN 'A' WHEN 'AC_MGT' THEN 'B' WHEN 'AC_ACCOUNT' THEN 'C' ELSE 'D' END; dbms_output.put_line(v_job_id || ' , ' || v_grade); END; /* 迴圈知識點 */ --使用迴圈列印數字1-100 -- 1初始化條件 2迴圈體 3迴圈條件 4迭代條件 DECLARE --1 v_number NUMBER(6) := 1;--定義一個變數並賦值 (:=是賦值符號) BEGIN LOOP --2 dbms_output.put_line('數字' || v_number); --3 EXIT WHEN v_number > 100; --4 v_number := v_number + 1; END LOOP; END; -- DECLARE v_number NUMBER(6) := 1; BEGIN LOOP dbms_output.put_line('數字' || v_number); EXIT WHEN v_number >= 100; v_number := v_number + 1; -- 可以放在這裡 END LOOP; END; --以下這樣寫也可以 DECLARE v_number NUMBER(6) := 1; BEGIN LOOP dbms_output.put_line('數字' || v_number); v_number := v_number + 1; --也可以放在這裡 EXIT WHEN v_number >= 100; END LOOP; END; -- DECLARE v_number NUMBER(6) := 1; BEGIN LOOP dbms_output.put_line('數字' || v_number); v_number := v_number + 1; -- EXIT WHEN v_number > 100; END LOOP; END; -- DECLARE v_number NUMBER(6) := 1; BEGIN LOOP dbms_output.put_line('數字' || v_number); v_number := v_number + 1; -- EXIT WHEN v_number > 100; END LOOP; END; --第二種迴圈方式 while DECLARE v_number NUMBER(6) := 1; BEGIN WHILE v_number <= 100 LOOP dbms_output.put_line('數字' || v_number); v_number := v_number + 1; END LOOP; END; /* 每迴圈一次,迴圈變數自動加1;使用關鍵字REVERSE,迴圈變數自動減1。 跟在IN REVERSE 後面的數字必須是從小到大的順序,而且必須是整數, 不能是變數或表示式。可以使用EXIT 退出迴圈 */ --第三種迴圈方式 for迴圈 BEGIN FOR mynumber IN 1..100 LOOP dbms_output.put_line('數字' || mynumber); END LOOP; END; --使用REVERSE(反轉)關鍵字 BEGIN FOR mynumber IN REVERSE 1..100 LOOP dbms_output.put_line('數字' || mynumber); END LOOP; END; --null語句 /* NULL:在PL/SQL 程式中,可以用 null 語句來說明“不用做任何事情”的意思,相當於一個佔位符,可以使某些語句變得有意義,提高程式的可讀性 */ --從employees表中查資料,如果薪水大於20000,則列印'土豪,我們做個朋友吧',如果薪水小於20000,不做任何處理 DECLARE v_salary employees.salary%Type ; BEGIN SELECT salary INTO v_salary FROM employees WHERE employee_id = 100; IF v_salary > 20000 THEN dbms_output.put_line('土豪,我們做個朋友吧'); ELSE NULL; --null語句 END IF; END; -- SELECT SQRT(2), SQRT(3), SQRT(4), SQRT(16), SQRT(9), SQRT(36) FROM dual; SELECT MOD(4, 2), MOD(36, 4), MOD(25, 6) FROM dual; -- /* 輸出2-100之間的質數 (java的面試中很多時候都會考這道題目,不光可以考察多層巢狀迴圈,還可以考察break、sqrt()函式、 小演算法、條件判斷結構、效率效能等等知識點,而且題目還不算太大太難,所以大家最好要會寫) */ --使用while寫法 DECLARE V_I NUMBER(5) := 2; V_J NUMBER(5) := 2; V_FLAG NUMBER(1) := 1; BEGIN WHILE V_I <= 100 LOOP WHILE V_J <= SQRT(V_I) LOOP IF MOD(V_I, V_J) = 0 THEN V_FLAG := 0; END IF; V_J := V_J + 1; END LOOP; IF V_FLAG = 1 THEN DBMS_OUTPUT.PUT_LINE('質數' || V_I); END IF; V_I := V_I + 1; V_FLAG := 1; -- V_J := 2; --這行程式碼註釋掉就無法求出正確的質數 V_J := 2; END LOOP; DBMS_OUTPUT.PUT_LINE('內層迴圈的V_J=' || V_J); END; --使用for迴圈的寫法,如下 DECLARE V_FLAG NUMBER(1) := 1; V_COUNT NUMBER(10) := 0; BEGIN FOR i IN 2..100 LOOP FOR j IN 2..sqrt(i) LOOP IF(MOD(i, j) = 0) THEN V_FLAG := 0; END IF; END LOOP; IF(V_FLAG = 1) THEN dbms_output.put_line('質數' || i); V_COUNT := V_COUNT + 1; --統計有幾個質數 END IF; V_FLAG := 1; END LOOP; dbms_output.put_line('共有' || V_COUNT || '個質數'); END; --改進上面的程式碼,使效率更高 DECLARE V_FLAG NUMBER(1) := 1; V_COUNT NUMBER(10) := 0; BEGIN FOR i IN 2..100 LOOP FOR j IN 2..sqrt(i) LOOP IF(MOD(i, j) = 0) THEN V_FLAG := 0; --PL/SQL中GOTO語句是無條件跳轉到指定的標號去的意思 GOTO LABEL; --(這裡使用GOTO提高了效率效能) END IF; END LOOP; <<LABEL>> IF(V_FLAG = 1) THEN dbms_output.put_line('質數' || i); V_COUNT := V_COUNT + 1; --統計有幾個質數 END IF; V_FLAG := 1; END LOOP; dbms_output.put_line('共有' || V_COUNT || '個質數'); END; --使用 goto --列印1——100的自然數,當列印到50時,跳出迴圈,輸出“列印結束” --方式1 DECLARE v_number NUMBER(5) := 100; --賦值 BEGIN FOR mynumber IN 1.. v_number LOOP IF mynumber = 50 THEN GOTO LABEL; END IF; dbms_output.put_line('自然數' || mynumber); END LOOP; <<LABEL>> dbms_output.put_line('列印結束'); END; -- BEGIN FOR I IN 1 .. 100 LOOP DBMS_OUTPUT.PUT_LINE(I); IF (I = 50) THEN GOTO LABEL; END IF; END LOOP; <<LABEL>> DBMS_OUTPUT.PUT_LINE('列印結束'); END; --方式2(使用exit關鍵字) DECLARE v_number NUMBER(5) := 100; --賦值 BEGIN FOR mynumber IN 1.. v_number LOOP IF mynumber = 50 THEN dbms_output.put_line('列印結束'); EXIT; --使用exit關鍵字 END IF; dbms_output.put_line('自然數' || mynumber); END LOOP; END; --(使用exit關鍵字) DECLARE v_number NUMBER(5) := 100; --賦值 BEGIN FOR mynumber IN 1.. v_number LOOP IF mynumber = 50 THEN EXIT; --使用exit關鍵字 END IF; dbms_output.put_line('自然數' || mynumber); END LOOP; dbms_output.put_line('列印結束'); END;