Below you will find pages that utilize the taxonomy term “PL/SQL”
Posts
>-
條款四十四,總是使用 WHILE loop 去處理 loose array。
像是下面這樣的程式用 FOR loop 去遍巡處理 loose array,這不是被建議使用的寫法,雖然大部分的狀況下可以正常運行,但是當 loose array 的內容被刪除時,這樣的處理會因為 null 元素而運行錯誤。
DECLARE ... l_index PLS_INTEGER; BEGIN ... IF t_employees IS NOT NULL THEN <<process_employees>> FOR i IN 1..t_employees.COUNT() LOOP ... END LOOP process_employees; END IF; END; 建議使用 WHILE loop 遍巡處理 loose array,才不會因為 Null 元素導致錯誤。
DECLARE ... l_index PLS_INTEGER; BEGIN l_index := t_employees.FIRST(); <<process_employees>> WHILE l_index IS NOT NULL LOOP ... l_index := t_employees.NEXT(l_index); END LOOP process_employees; END;
read morePosts
>-
條款四十三,遍巡 dense array 時,建議使用 1 當做 lower boundary,使用 COUNT() 當做 upper boundary。
像是下面這樣的程式,使用了 FIRST() 與 LAST() 做為遍巡走訪的條件,dense array 不為空時可以正常運作,但當 dense array 為空時則會發生錯誤。
DECLARE t_employees t_employee_type := t_employee_type(); BEGIN <<process_employees>> FOR i IN t_employees.FIRST()..t_employees.LAST() LOOP … END LOOP process_employees; END; 簡單的解決方式可以加判斷 dense array 是否為空。
DECLARE t_employees t_employee_type := t_employee_type(); BEGIN <<process_employees>> IF t_employees IS NOT EMPTY THEN FOR i IN t_employees.FIRST()..t_employees.LAST() LOOP … END LOOP process_employees; END IF; END; 但建議的方式是改以 1 與 COUNT() 做為遍巡走訪的條件。
read morePosts
>-
條款四十二,總是使用 NUMERIC FOR loop 去處理 dense array。
像是下面這樣的程式:
... BEGIN <<process_employees>> LOOP EXIT process_employees WHEN i > t_employees.COUNT(); … i := i + 1; END LOOP process_employees; END; 可以像下面這樣改寫,程式碼的維護性會比較好。
... BEGIN <<process_employees>> FOR i IN 1..t_employees.COUNT() LOOP … END LOOP process_employees; END;
read morePosts
PL/SQL SQL CODING GUIDELINE 39 - Never use GOTO statements in your code
條款三十九,從不使用 GOTO 語句。
像是下面這樣的程式。
... BEGIN ... <<check_digit>> FOR i IN co_lower_bound .. l_len_array LOOP <<check_pw_char>> FOR j IN co_lower_bound .. l_len_pw LOOP IF SUBSTR(in_password, j, 1) = SUBSTR(co_digitarray, i, 1) THEN l_isdigit := TRUE; GOTO check_other_things; END IF; END LOOP check_pw_char; END LOOP check_digit; <<check_other_things>> NULL; IF NOT l_isdigit THEN raise_application_error(co_errno, co_errmsg); END IF; END password_check; ... 可考慮使用 exit 搭配 label 從迴圈內跳離。
... BEGIN ... <<check_digit>> FOR i IN co_lower_bound .
read morePosts
>-
條款四十一,總是使用 CURSOR for loop,除非使用 Bulk operations。
像是下面這樣的程式:
... BEGIN <<read_employees>> LOOP FETCH c_employees INTO r_employee; EXIT read_employees WHEN c_employees%NOTFOUND; … END LOOP read_employees; CLOSE c_employees; END; 可以像下面這樣改寫,程式碼的維護性會比較好。
... BEGIN <<read_employees>> FOR r_employee IN c_employee LOOP … END LOOP read_employees; END;
read morePosts
PL/SQL SQL CODING GUIDELINE 40 - Always label your loops
條款四十,如果程式中有 loop,嘗試使用 label 讓他的區塊範圍更為清楚。
像是下面這樣的程式:
BEGIN FOR r_employee IN (SELECT * FROM emp) LOOP … END LOOP; END; 可以像下面這樣改寫,在 loop 的前面加上 Label,然後在 End 後加上 Label Name。
BEGIN <<process_employees>> FOR r_employee IN (SELECT * FROM emp) LOOP … END LOOP process_employees; END; 這樣程式碼的區塊範圍清楚許多。
read morePosts
>-
條款三十八,如果 NVL 第二或第三個參數是 function 呼叫或是 select 語句,使用 CASE 取代 NVL2。
這是因為 NVL2 會先把每個可能的結果都先取出,儘管是根本不會出的結果,所以這樣會有不必要的 overhead。
SELECT NVL2(dummy, function_call(), function_call()) FROM dual; 建議的做法是用 CASE 取代 NVL2,以避開這樣的問題。
SELECT CASE WHEN dummy IS NULL THEN function_call() ELSE function_call() END FROM dual;
read morePosts
PL/SQL SQL CODING GUIDELINE 36 - Try to use CASE rather than DECODE
條款三十六,嘗試使用 CASE 而不要用 DECODE。
用 DECODE 的可讀性較低,不易閱讀。
BEGIN SELECT DECODE(dummy, 'A', 1 , 'B', 2 , 'C', 3 , 'D', 4 , 'E', 5 , 'F', 6 , 7) INTO l_result FROM dual; ... 改用 CASE 撰寫雖然程式變多,但閱讀起來相對會比較清楚。
BEGIN l_result := CASE dummy WHEN 'A' THEN 1 WHEN 'B' THEN 2 WHEN 'C' THEN 3 WHEN 'D' THEN 4 WHEN 'E' THEN 5 WHEN 'F' THEN 6 ELSE 7 END; ...
read morePosts
>-
條款三十四,避免在 SQL 語句運行與 implicit cursor 中間使用 procedure 或是 function。
像是下面的例子,這邊先刪除了一些資料,後續要用 SQL%ROWCOUNT 去判斷刪除的筆數,但中間卻調用了其它 function,以致於 SQL%ROWCOUNT 的值不如我們的預期。
CREATE PROCEDURE remove_emp_and_process (in_id IN emp.empno%TYPE) AS BEGIN DELETE FROM emp WHERE empno = in_id RETURNING deptno INTO l_deptno; process_department (...); IF SQL%ROWCOUNT > 1 THEN -- Too many rows deleted! Rollback and recover... ROLLBACK; END IF; END remove_emp_and_process; 所以我們必須避免在 SQL 語句運行與 implicit cursor 中間使用 procedure 或是 function。
read morePosts
PL/SQL SQL CODING GUIDELINE 33 - Always close locally opened cursors
條款三十三,總是關閉開啟的游標。
像是下面這樣將游標開啟後並未揪游標關閉,使用的資源不會自動釋放。
CREATE PROCEDURE not_close_cursor (out_count OUT INTEGER) AS CURSOR c1 IS SELECT COUNT (*) FROM all_users; BEGIN out_count := 0; OPEN c1; FETCH c1 INTO out_count; END not_close_cursor; ... 應該要自己將游標在適當的時機點關閉,使用的資源才會被釋放。
CREATE PROCEDURE close_cursor (out_count OUT INTEGER) AS CURSOR c1 IS SELECT COUNT (*) FROM all_users; BEGIN out_count := 0; OPEN c1; FETCH c1 INTO out_count; CLOSE c1 END close_cursor;
read morePosts
>-
條款三十二,當使用 BULK 與 LIMIT 操作時,避免直接在後面用 %NOTFOUND 判斷是否有資料處理,應改用 COUNT() 判斷。
像是下面這樣的撰寫方式,迴圈內每次會處理 5 筆資料,假設今天總資料量為 14,那第三次處理時因為剩餘的筆數 4 小於 LIMIT 設定的筆數 5,%NOTFOUND 會為 true 跳離,剩餘的資料就都沒有跑到。
-- This example will only show 10 of 14 employees DECLARE TYPE t_employee_type IS TABLE OF emp%ROWTYPE; t_employees t_employee_type; CURSOR c_emp IS SELECT * FROM emp ORDER BY empno; BEGIN OPEN c_emp; <<process_emp>> LOOP FETCH c_emp BULK COLLECT INTO t_employees LIMIT 5; EXIT process_emp WHEN c_emp%NOTFOUND; <<display_emp>> FOR i IN 1.
read morePosts
>-
條款三十一,Always use %NOTFOUND instead of NOT %FOUND to check whether a cursor was successful。
不要用 Not %FOUND 去撰寫判斷邏輯。
LOOP FETCH c_employees INTO r_employee; EXIT WHEN NOT c_employees%FOUND; ... END LOOP; 取而代之的是要用 %NOTFOUND 去撰寫判斷邏輯。
LOOP FETCH c_employees INTO r_employee; EXIT WHEN c_employees%NOTFOUND; ... END LOOP; 這樣可讀性會比較好。
read morePosts
>-
條款二十九,Try to use anchored records as targets for your cursors。
像是下面這邊的程式就宣告了幾個變數,開啟 Cursor 後遍巡,將資料塞到變數後再進一步處理。
DECLARE CURSOR c_user IS SELECT user_id, firstname, lastname FROM user; l_user_id user.user_id%TYPE; l_firstname user.firstname%TYPE; l_lastname user.lastname%TYPE; BEGIN OPEN c_user; FETCH c_user INTO l_user_id, l_firstname, l_lastname; WHILE c_user%FOUND LOOP FETCH c_user INTO l_user_id, l_firstname, l_lastname; END LOOP; CLOSE c_user; END; 如果改用 cursor-anchored records 去實作,就可以省去一些不必要的變數宣告。
DECLARE CURSOR c_user IS SELECT user_id, firstname, lastname FROM user; r_user c_user%ROWTYPE; BEGIN OPEN c_user; FETCH c_user INTO r_user; <<process_user>> WHILE c_user%FOUND LOOP FETCH c_user INTO r_user; END LOOP process_user; CLOSE c_user; END;
read morePosts
>-
條款二十六,運行插入命令時總是指定塞入的欄位。
像是下面這樣不指定要塞入欄位的寫法,塞入的動作會對資料表欄位的順序有所依賴,當欄位順序一有變動就會產生不如預期的結果,而且問題發生時不是很容易可以被偵測出來。
INSERT INTO messages VALUES (l_mess_no ,l_mess_typ ,l_mess_text ); 如果在塞入時明確的指定塞入的欄位,就能避開這樣的問題。
INSERT INTO messages (mess_no ,mess_typ ,mess_text ) VALUES (l_mess_no ,l_mess_typ ,l_mess_text );
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 25 - Avoid using the LONG and LONG RAW data types
條款二十五,避免使用 LONG 與 LONG RAW 型態。
LONG 與 LONG RAW 型態已經過時,留著只是為了向前相容,不建議拿來使用,應考慮用 NCLOB、BLOB、BFILE 去替。
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 24 -Try to use boolean data type for values with dual meaning
條款二十四,當值只有兩種狀態時,試著使用 Boolean 型態。
像是如果要表達的是是否為較大的數值,如果沒有特別的理由,那就不該使用數值表示,因為數值代表的意義沒有 Boolean 型態來的明確。
DECLARE v_IsBigger number(1) := 1; BEGIN DBMS_OUTPUT.PUT_LINE(CASE WHEN v_IsBigger = 1 THEN 'True' ELSE 'False' END); END; 若用 Boolean 型態表達會比較清楚。
DECLARE v_IsBigger BOOLEAN := true; BEGIN DBMS_OUTPUT.PUT_LINE(CASE WHEN v_IsBigger THEN 'True' ELSE 'False' END); END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 23 - Always define your VARCHAR2 variables using CHAR SEMANTIC
條款二十三,使用 Varchar2 時總是定義 Char Semantic。
預設未定義時有可能指定的是 Byte,也有可能是 Char,端看 NLS_LENGTH_SEMANTICS 參數的設定,預設是 Byte。
DECLARE v_str varchar(200); BEGIN ... END; 但通常我們指定字串應該看的是字元數,建議是將其指定用 Char。
DECLARE v_str varchar(200 char); BEGIN ... END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 22 - Never use zero-length strings to substitute NULL
條款二十二,不要用空字串去代替 Null 值。
在 Oracle 這邊不論是對的 Varchar 或是 Varchar2 型態賦予空字串,Oracle 都會將其視為 Null,所以這邊不建議將其設為空字串。
DECLARE v_str varchar2(4000) := ''; BEGIN DBMS_OUTPUT.PUT_LINE(CASE WHEN v_str is null THEN 'null' ELSE 'not null' END); END; 而是應該像下面,沒特別塞值時預設就是 Null。
DECLARE v_str varchar2(4000); BEGIN DBMS_OUTPUT.PUT_LINE(CASE WHEN v_str is null THEN 'null' ELSE 'not null' END); END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 21 - Avoid using VARCHAR data type
條款二十一,避免使用 Varchar 型態。
Varchar 型態在工業標準上是可以儲存空字串的,但在 Oracle 這邊並未遵循這樣的標準,當將空字串存放至 Varchar 型態,Oracle 這邊會將空字串變為 null 值,就跟 Varchar2 型態是一樣的,但難保哪天會改回遵循工業標準。
DECLARE v_str varchar(4000); BEGIN … END; 因此在 Oracle 這邊建議不要使用 Varchar 型態,建議使用 Varchar2 型態。
DECLARE v_str varchar2(4000); BEGIN … END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 20 - Avoid using CHAR data type
條款二十,避免使用 Char。
Oracle 的 Char 型態在宣告時需指定大小,宣告多大就佔多大。像是下面這邊筆者宣告了 4000 的 char,則該變數即佔了 4000,儘管這邊只賦予了短短的幾個字元進去。
DECLARE v_str char(4000) := 'test'; BEGIN DBMS_OUTPUT.PUT_LINE(Length(v_str)); END; 取而代之的是應該改用 varchar2 型態。
DECLARE v_str varchar2(4000) := 'test'; BEGIN DBMS_OUTPUT.PUT_LINE(Length(v_str)); END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 19 - Try to use PLS_INTEGER instead of NUMBER for arithmetic operations with integer values (no decimal point)
條款十九,用 PLS_INTEGER 去表示整數。
如果要宣告整數,不要用 Number 型態去宣告。
DECLARE v_number number(38, 0); BEGIN ... END; 建議使用 PLS_INTEGER,因為使用 PLS_INTEGER 型態使用的記憶體會比較少,且效能上會快上三倍。
DECLARE v_number PLS_INTEGER; BEGIN ... END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 18 - Avoid declaring NUMBER variables or subtypes with no precision
條款十八,避免在宣告 Number 型態的變數或是 SubType 時未設定整數位數。
像是下面這樣,變數宣告時未指定整數位數,預設精確度為 38 位。
DECLARE v_number number; BEGIN ... END; 如果使用上已經知道明確位數,那建議在宣告時還是明確的指定。
DECLARE v_number number(9, 2); BEGIN ... END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 15 - Never use quoted identifiers
條款十五是說在變數宣告時,變數的名稱不要加上雙引號。
像是下面這樣,宣告的變數加上雙引號是合法的。
DECLARE "v_str" VARCHAR2(30) ; BEGIN … END main; 但不建議這樣宣告,建議還是不要加上雙引號。
DECLARE v_str VARCHAR2(30) ; BEGIN … END main;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 14 - Never overload data structure usages
條款十四是說不要去覆寫變數。
像是下面這樣外層與內層宣告了一樣名稱的變數,是不建議的寫法。
<<main>> DECLARE v_str VARCHAR2(30); BEGIN <<sub>> DECLARE v_str VARCHAR2(4000) ; BEGIN … END sub; END main; 建議使用上還是應該要將變數名稱錯開。
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 13 - Avoid initializing variables using functions in the declaration section
條款十三是說要避免在變數宣告的同時呼叫 function 去初始變數。
DECLARE l_company_name VARCHAR2(30) := util_pck.get_company_name(in_id => 47); BEGIN … END; 因為在變數宣告的地方呼叫 function 去初始變數,function 發生例外時是無法攔截處理的。
因此要像下面這樣將宣告與初始拆開處理。
DECLARE v_str VARCHAR2(30); BEGIN <<init>> BEGIN v_str := util_pck.get_company_name(inId => 47); EXCEPTION WHEN VALUE_ERROR THEN ... END init; END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 12 - Avoid comparisons with null value
條款十二是在說當判斷變數是否為 null 時,不要像下面這樣使用 = 去判斷。
DECLARE v_str VARCHAR2(30); BEGIN if v_str = null then … end if; END; 因為 null 不等於任何東西,即使是 null 也不等於 null。
{% img /images/posts/PLSQLCopRule12/1.png %}
正確的方式應該是用 is 或 is not 去做判斷。
DECLARE v_str VARCHAR2(30); BEGIN if v_str is null then … end if; END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 11 - Never initialize variables with NULL
條款十一是說不要將變數初始為 NULL。
DECLARE v_str VARCHAR2(30) := null; BEGIN ... END; 因為預設就是初始為 Null。
DECLARE v_str VARCHAR2(30); BEGIN ... END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 10 - Try to use subtypes for constructs used often in your application
條款十是在說如果有些常用的型態使用,建議將它設成 SubType,像是下面這邊 VARCHAR2(4000) 程式中如果常用的話,就可以將它設成 SubType。
DECLARE v_str VARCHAR2(4000); BEGIN … END; 這邊將它設成名為 STRING_MAX 的 SubType,後續可直接拿來宣告使用。
CREATE OR REPLACE PACKAGE PKG_SUBTYPE AS SUBTYPE STRING_MAX IS VARCHAR2(4000); END PKG_SUBTYPE; DECLARE v_str PKG_SUBTYPE.STRING_MAX; BEGIN ... END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 9 - Try to have a single location to define your types
條款九主要是在描述型態的定義要集中一處放置,以 Oracle 來說型態的定義可以放置在 DB 的 Types 下。
{% img /images/posts/PLSQLCopRule9/1.png %}
也可以建造個 Package 集中放置,這邊建議是挑選一個地方放置即可,避免有些型態的宣告放置在 Types 下,而有的在 Package 下。
選用上要注意 Oracle 內的型態有的只能在 Database 下使用,無法在 Package 下使用,像是 Object 型態。
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 8 - Try to use anchored declarations for variables
條款八,使用 anchored declarations。
像是下面這樣的程式:
DECLARE v_empName VARCHAR2(10); BEGIN … END; 預期要帶入的是 emp table 的 ename,這在 emp table 的 schema 中是其實是已經定義好的。如果像上面這樣另行宣告可能會不小心設錯,或是 schema 修改時會很麻煩。
若是使用 anchored declarations,型態會直接參照 schema 的定義,免去像這樣的困擾。
DECLARE v_empName emp.ename%TYPE; BEGIN … END;
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 5 - Avoid using literals in your code
條款五,避免在程式中直接使用字串。
像是下面這樣的程式:
SET SERVEROUTPUT ON Begin DBMS_OUTPUT.put_line('Root Account:' || 'Admin'); End; 可以像下面這樣改寫,建立一個 Package 統一存放常數字串,呼叫端改透過 Package 叫用。
SET SERVEROUTPUT ON CREATE OR REPLACE PACKAGE CONST IS ROOT_ACCOUNT CONSTANT varchar(50) := 'Admin'; END CONST; / Begin DBMS_OUTPUT.put_line('Root Account:' || CONST.ROOT_ACCOUNT); End; 這樣常數字串的宣告會集中在 Package 內,修改上也比較方便。
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 2 - Always have a matching loop or block label
條款二,如果程式中有迴圈區塊,為其加上 label 讓他的區塊範圍更為清楚。
像是下面這樣的程式:
SET SERVEROUTPUT ON DECLARE i PLS_INTEGER; Begin FOR i IN 1..10 LOOP DBMS_OUTPUT.put_line('i =' || i); End LOOP; End; 可以像下面這樣改寫,在 For…Loop 前面加上 Label,然後在 End 後加上 Label Name。
SET SERVEROUTPUT ON DECLARE i PLS_INTEGER; Begin <<Print1To10>> FOR i IN 1..10 LOOP DBMS_OUTPUT.put_line('i =' || i); End LOOP Print1To10; End; 改完程式碼的區塊範圍清楚了許多。
read morePosts
PL/SQL amp; SQL CODING GUIDELINE 1 - Try to label your sub blocks
條款一,如果程式中有子 block,嘗試使用 label 讓他的區塊範圍更為清楚。
像是下面這樣的程式:
SET SERVEROUTPUT ON Begin DBMS_OUTPUT.put_line('Start'); Begin DBMS_OUTPUT.put_line('Processing...'); End; DBMS_OUTPUT.put_line('End'); End; 可以像下面這樣改寫,在子 Block 的 Begin 前面加上 Label,然後在 End 後加上 Label Name。
SET SERVEROUTPUT ON Begin DBMS_OUTPUT.put_line('Start'); <<Processing>> Begin DBMS_OUTPUT.put_line('Processing...'); End Processing; DBMS_OUTPUT.put_line('End'); End; 改完程式碼的區塊範圍清楚了許多。
read morePosts
PL/SQL - EXTRACT Function
EXTRACT function 可擷取日期或時間中指定部分的資料。
使用語法如下:
EXTRACT ( { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND } | { TIMEZONE_HOUR | TIMEZONE_MINUTE } | { TIMEZONE_REGION | TIMEZONE_ABBR } FROM { date_value | interval_value } ) 我們可以帶入日期並指定擷取 年、月、日,或是帶入時間並指定擷取 時、分、秒。
像是要擷取現在是西元幾年,可以像下面這樣叫用:
EXTRACT(year from sysdate) 要擷取現在是幾點,可以像下面這樣叫用:
EXTRACT(hour from systimestamp) 使用上會像下面這樣:
{% img /images/posts/ExtractFunction/1.png %}
Link Oracle/PLSQL: EXTRACT Function
read morePosts
PL/SQL - MONTHS_BETWEEN Function
MONTHS_BETWEEN function 可計算兩個日期相差多少月份。
使用語法如下:
MONTHS_BETWEEN( date1, date2 ) 帶入的兩個日期,若第一個日期大過第二個日期,則回傳正值的月份差。反之則回傳負值月份差。
像是下面這樣叫用就會傳回 2:
MONTHS_BETWEEN(ADD_MONTHS(sysdate, 2), sysdate) 像下面這樣叫用就會傳回 -2:
MONTHS_BETWEEN(sysdate, ADD_MONTHS(sysdate, 2)) 使用上會像下面這樣:
{% img /images/posts/MonthsBetweenFunction/1.png %}
Link Oracle/PLSQL: MONTHS_BETWEEN Function
read morePosts
PL/SQL - LAST_DAY function
LAST_DAY function 會依帶入的日期回傳對應月份的最後一天。
使用語法如下:
LAST_DAY( date ) 其中 date 為要處理的日期,帶入即會回傳對應月份的最後一天。
像是要取得當月的最後一天,可以像下面這樣叫用:
last_day(sysdate) 使用上會像下面這樣:
{% img /images/posts/LastDayFunction/1.png %} Link Oracle/PLSQL: LAST_DAY Function
read morePosts
PL/SQL - NEXT_DAY function
NEXT_DAY function returns the first weekday that is greater than a date。
使用語法如下:
NEXT_DAY( date, weekday ) 其中 date 為基準日,weekday 指定要回傳的日期為星期幾。
weekday 可為 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY。
像是要找尋下一個星期日,可這樣叫用:
next_day(sysdate, 'SUNDAY') 使用上會像下面這樣:
{% img /images/posts/NextDayFunction/1.png %}
Link Oracle/PLSQL: NEXT_DAY Function
read morePosts
PL/SQL - ADD_MONTHS function
ADD_MONTHS function 可將帶入的日期月份做加減處理後回傳。
使用語法如下:
ADD_MONTHS( date1, number_months ) 其中 data1 為要做處理的日期,number_months 為要加減的月份。
number_months 帶入的值為正值,表示是要加上指定的月份,反之表示要減上指定的月份。
像是要將當前的日期加三個月,可這樣叫用:
add_months(sysdate, 3) 要將當前日期減三個月,可這樣叫用:
add_months(sysdate, -3) 使用上會像下面這樣:
{% img /images/posts/AddMonthsFunction/1.png %}
Link Oracle/PLSQL: ADD_MONTHS Function
read morePosts
PL/SQL - MOD function
MOD function 可傳回兩數相除後的餘數。
使用語法如下:
MOD( m, n ) 其中 m 為被除數,n 為除數。
所以如果要取 5/2 的餘數,可以像這樣寫。
Mod(5, 2) 使用上會像下面這樣:
{% img /images/posts/ModFunction/1.png %}
Link Oracle/PLSQL: MOD Function
read morePosts
PL/SQL - FLOOR function
FLOOR function 可傳回小於或等於指定數值的最大整數值。
使用語法如下:
FLOOR( number ) 使用上會像下面這樣:
{% img /images/posts/FloorFunction/1.png %}
Link Oracle/PLSQL: FLOOR Function
read morePosts
PL/SQL - CEIL function
CEIL function 可傳回大於或等於指定數值的最小整數值。
使用語法如下:
CEIL( number ) 使用上會像下面這樣:
{% img /images/posts/CeilFunction/1.png %}
Link Oracle/PLSQL: CEIL Function
read morePosts
PL/SQL - Round function
Round function 可將帶入的值依指定的位數下去做四捨五入運算並回傳。
使用語法如下:
ROUND( number [, decimal_places] ) number 是要做四捨五入的值,decimal_places 是要做四捨五入的位數。
這邊的 decimal_places 可以是正值,也可以是負值。如果是正值表示的是小數點後的位數,如果是負值則表示小數點前的位數。
寫起來就像下面這樣:
{% img /images/posts/RoundFunction/1.png %}
{% img /images/posts/RoundFunction/2.png %}
{% img /images/posts/RoundFunction/3.png %}
{% img /images/posts/RoundFunction/4.png %}
{% img /images/posts/RoundFunction/5.png %}
Link Oracle/PLSQL: ROUND Function (with numbers)
read morePosts
PL/SQL - ABS function
ABS function 會將帶入的值取絕對值傳出。
使用語法如下:
ABS( number ) number 為要轉換的數值,如果帶入的是負值,會將其變為正值傳出,就像下面這樣:
{% img /images/posts/ABSFunction/1.png %}
{% img /images/posts/ABSFunction/2.png %}
Link Oracle/PLSQL: ABS Function
read morePosts
PL/SQL - NUMTODSINTERVAL function
NUMTODSINTERVAL function 會將帶入的值轉成特定單位的 Interval。
使用語法如下:
NUMTODSINTERVAL( number, expression ) number 這邊帶入的是要轉換的值,expression 這邊帶入的是要轉換的單位,可以是 Day、 Hour、 Minute、 Second。
使用上可搭配日期使用,對日期做些增減處理。像是下面這樣:
{% img /images/posts/NUMTODSINTERVALFunction/1.png %}
{% img /images/posts/NUMTODSINTERVALFunction/2.png %}
{% img /images/posts/NUMTODSINTERVALFunction/3.png %}
{% img /images/posts/NUMTODSINTERVALFunction/4.png %}
{% img /images/posts/NUMTODSINTERVALFunction/5.png %}
{% img /images/posts/NUMTODSINTERVALFunction/6.png %}
Link Oracle/PLSQL: NUMTODSINTERVAL Function
read morePosts
PL/SQL - Sysdate function
Sysdate function 會回傳資料庫系統當前的日期與時間。
使用語法如下:
Sysdate 直接叫用即可,不需帶入任何的參數。
像是這樣:
{% img /images/posts/SysdateFunction/1.png %}
Link Oracle/PLSQL: SYSDATE function
read morePosts
PL/SQL - Decode function
Decode function 可用於取代簡單的 If-Then-Else 陳述式。
使用語法如下:
DECODE( expression , search , result [, search , result]... [, default] ) 簡單來說如果 expression 的值等同 search 值的話,則回傳對應的 result 值。
像是要將數值帶入,依其值決定要回傳 ’true’ 或是 ‘false’,可以像下面這樣撰寫:
{% img /images/posts/DecodeFunction/1.png %}
{% img /images/posts/DecodeFunction/2.png %}
Link Oracle/PLSQL: DECODE Function
read more