- kolekcji
- parametrów domyślnych
- typu SIMPLE_INTEGER ( ze względów wydajnościowych)
- tekst na wejściu ma mieć długość o jedną cyfrę dłuższą niż długość tablicy wag
- w jednakowy sposób obliczamy sumę kontrolną - różnica jest w dzielniku
- walidacja sumy kontrolnej z ostatnim cyfrą wprowadzonego literału występuje w dwóch wersjach dla PESEL oraz dla NIP i REGON
- każda z funkcji zwraca jeden jeśli parametr jest poprawny i zero w przeciwnym przypadku
- pragma WNDS umozliwia wywołanie funkcji na poziomie SQL
- argument może być dowolnej długości i zawierać dowolną liczbę znaków nie będących cyframi za pomocą wyrażeń regularnych usuniemy je
- deklaracja tablic wag w części deklaratywnej ciała pakietu poprawiło wydajność o około 20% w porównaniu z deklaracja tablic wag wewnątrz ciał funkcji. Tablice tworzone są podczas pierwszego wywołania w danej sesji bazodanowej
- jest to kod szybki, ale stanowi pewien kompromis pomiędzy wydajnością a czytelnością
- kompilacja za pomocą poniższych parametrów (do kodu maszynowego z zaawansowaną optymalizacją) zwiększa wydajność około dwukrotnie: ALTER PACKAGE PCKG_WALIDUJ_IDS COMPILE PLSQL_CODE_TYPE = NATIVE PLSQL_OPTIMIZE_LEVEL = 3
- jest to krótki protest przeciwko kodowaniu metodą kopiuj & wklej
- wymagany jest Oracle 11g
CREATE OR REPLACE PACKAGE PCKG_WALIDUJ_IDS AS
FUNCTION FDB_Waliduj_NIP(pc_NIP VARCHAR2) RETURN INTEGER;
FUNCTION FDB_Waliduj_PESEL(pc_PESEL VARCHAR2) RETURN INTEGER;
FUNCTION FDB_Waliduj_REGON(pc_REGON VARCHAR2) RETURN INTEGER;
PRAGMA RESTRICT_REFERENCES(FDB_Waliduj_NIP, WNDS);
PRAGMA RESTRICT_REFERENCES(FDB_Waliduj_PESEL, WNDS);
PRAGMA RESTRICT_REFERENCES(FDB_Waliduj_REGON, WNDS);
END;
/
CREATE OR REPLACE PACKAGE BODY PCKG_WALIDUJ_IDS IS
------------------------------------------------------
TYPE t_Wagi IS TABLE OF SIMPLE_INTEGER;
vt_NIP t_Wagi := t_Wagi(6, 5, 7, 2, 3, 4, 5, 6, 7 );
vt_PESEL t_Wagi := t_Wagi(1, 3, 7, 9, 1, 3, 7,9,1,3);
vt_REGON_9 t_Wagi := t_Wagi(8, 9, 2, 3, 4, 5, 6, 7);
vt_REGON_14 t_Wagi := t_Wagi( 2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8);
----------------------
FUNCTION PDB_Waliduj( pc_Literal VARCHAR2, pt_Wagi IN t_Wagi,
pn_Modulo SIMPLE_INTEGER, pb_PESEL BOOLEAN :=FALSE) RETURN NUMBER
IS
vc_Literal VARCHAR2(14 CHAR);
vn_SumaKontr SIMPLE_INTEGER:=0;
BEGIN
IF NVL(REGEXP_COUNT(pc_Literal,'[[:digit:]]'),0) <> pt_Wagi.COUNT + 1 THEN
RETURN 0;
END IF;
---Suma kontrolna
vc_Literal := REGEXP_REPLACE( pc_Literal,'[^[:digit:]]','');
FOR i IN 1..pt_Wagi.COUNT
LOOP
vn_SumaKontr := vn_SumaKontr + TO_NUMBER(SUBSTR( vc_Literal, i,1)) * pt_Wagi(i);
END LOOP;
---
vn_SumaKontr := MOD(vn_SumaKontr, pn_Modulo);
-- Dla NIP poniższy przypadek nie powinien wystąpić, dla PESEL nie wystąpi
IF vn_SumaKontr = 10 THEN
vn_SumaKontr := 0;
END IF;
-- PESEL
IF pb_Pesel THEN
IF vn_SumaKontr + TO_NUMBER(SUBSTR( vc_Literal, Length(vc_Literal),1)) IN ( 0, 10) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END IF;
-- NIP, REGON
IF vn_SumaKontr = TO_NUMBER(SUBSTR( vc_Literal, Length(vc_Literal),1)) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
----
FUNCTION FDB_Waliduj_NIP(pc_NIP VARCHAR2) RETURN INTEGER
IS
BEGIN
RETURN PDB_Waliduj(pc_NIP, vt_NIP, 11);
END;
------------------------------------------------------
FUNCTION FDB_Waliduj_PESEL(pc_PESEL VARCHAR2) RETURN INTEGER
IS
BEGIN
RETURN PDB_Waliduj(pc_Pesel, vt_PESEL, 10, TRUE);
END;
------------------------------------------------------
FUNCTION FDB_Waliduj_REGON(pc_REGON VARCHAR2) RETURN INTEGER
IS
BEGIN
RETURN PDB_Waliduj(pc_REGON, vt_REGON_9, 11) +
PDB_Waliduj(pc_REGON, vt_REGON_14, 11);
END;
END;
/
Brak komentarzy:
Prześlij komentarz