銀行卡號最後一位為檢查碼,依 Luhn 演算法(Mod 10) 計算。本函數輸入卡號字串,回傳 'ok' 表示校驗通過,否則回傳正確的檢查碼字元,便於前端提示或自動修正。純 PL/SQL 實現,無外部相依,可直接部署於資料庫層。
CREATE OR REPLACE FUNCTION checkBankCard(p_bankcard IN VARCHAR2) RETURN VARCHAR2
-- 正確時返回 'ok',否則返回正確的校驗碼字元
IS
curval NUMBER := 0;
total NUMBER := 0;
everyother NUMBER := 1;
v_end NUMBER;
BEGIN
IF p_bankcard IS NULL THEN RETURN 'null'; END IF;
-- 從倒數第二位開始向左處理(跳過最後一位檢查碼)
FOR i IN REVERSE 1 .. (LENGTH(p_bankcard) - 1) LOOP
curval := TO_NUMBER(SUBSTR(p_bankcard, i, 1));
IF everyother = 1 THEN
everyother := 0;
curval := curval * 2;
IF curval > 9 THEN curval := curval - 9; END IF; -- 兩位數相加等同減 9
ELSE
everyother := 1;
END IF;
total := total + curval;
END LOOP;
-- 計算應有的檢查碼
IF MOD(total, 10) = 0 THEN v_end := 0;
ELSE v_end := 10 - MOD(total, 10);
END IF;
-- 比對最後一位
IF TO_CHAR(v_end) = SUBSTR(p_bankcard, LENGTHB(p_bankcard), 1) THEN
RETURN 'ok';
ELSE
RETURN TO_CHAR(v_end);
END IF;
END;
'ok',不符返回正確檢查碼