Zdecydowaną większość z poniższych błędów i ja sam popełniałem
1
.Niewłaściwa obsługa wyjątków
BEGIN
....
.....
EXCEPTION
WHEN OTHERS THEN COMMIT ;
END;
Wprawdzie kompilator PL/SQL w wersji 11g wykrywa instrukcje
WHEN OTHERS THEN NULL, ale traktowane są jako ostrzeżenia i to przy włączonej opcji
PLSQL_WARNINGS='ENABLE:ALL'. W skrajnych przypadkach dla zaharmonogramowanych jobów; brak obsługi wyjątków jest w stanie w wiecznej pętli uruchamiać błędny kod i skonsumować istotną część zasobów bazy
2.
Brak NVL w algorytmach obliczeniowych
DECLARE
a
INTEGER;
b
INTEGER :=1;
BEGIN
DBMS_OUTPUT.PUT_LINE(a + b);
END:
inna sprawa, że wg mnie pola używane do obliczeń powinny być
DEFAULT 0
NOT NULL. Nawet jeśli się to przestrzega, warto wstawiać
NVL dla świętego spokoju..
Nieznajomość faktu, że niektóre funkcje agregujące np
AVG zadziałają inaczej dla wartości
NULL i
NOT NULL
SELECT AVG(pole_liczbowe)
FROM tabela
zadziała inaczej
SELECT AVG(
NVL(pole_liczbowe,0))
FROM tabela
jeśli pole_liczbowe bedzie przyjmować wartości NULL
3
Nadużywanie DBMS_OUTPUT w pętlach
4.
Warunek LENGTH(
zmienna_tekstowa) = 0 zamiast
zmienna_tekstowa IS NULL
5.
Deklarowanie zmiennych odpowiadających polom w tabeli bez korzystania z zakotwiczeń %TYPE. Szczególnie ciekawym przypadkiem jest inna maksymalna długość
VARCHAR2 w polu tabeli i jako zmienna w kodzie
6. W obrębie bazy deklarowanie tabel z polami
VARCHAR2 ( size
CHAR)i
VARCHAR2( size
BYTE)
7. Nadużywanie dynamicznego SQL - chociaż czasami bywa niezbędny. Szczególnie niebezpieczny jest
SQL wykonujący operacje
DDL, np.
TRUNCATE TABLE,
CREATE INDEX,
DROP INDEX... Polecenia DDL wywołują niejawne zatwierdzanie transakcji, co może w sposób bardzo skuteczny zniszczyć logike transakcyjną aplikacji w PL/SQL
8. Nadawanie id rekordom w inny sposób niż przy użyciu sekwencji
9. Dokonywanie konwersji ze stringów na liczby i na daty bez podania masek - taki kod jest nieprzenośny zupełnie
10. Stosowanie zmiennych typu CHAR
11.
Niepodawanie obiektom baz danych w kodzie PL/SQL nazw schematów. I to wszystkim bez wyjątku !!! Czasami w dużej bazie może pojawić się kilka tabel klienci w rożnych schematach i mamy pewne źródło problemów. Przy migracji i scalaniu baz podawanie ownerów mocno ułatwia życie... Dlatego też sądzę, że dla kluczowych tabel należy tworzyć publiczne synonimy coby mniej rozgarnięci userzy nie popełnili ich w swoich schematach...
12.
Stosowanie wskazówek w zapytaniach.
SELECT /*+ INDEX( t idx_klienci_nazwa) */ FROM schemat.tbl_klienci t
WHERE t.nazwa = vc_Nazwa
Po mojemu hintów już od bazy 10g nie powinno się używać - wbudowany optymalizator radzi sobie z optymalizacją dobrze. Zaszycie hinta niesie za sobą niebezpieczeństwa związane z przebudową, usunięciem, rozszerzeniem indeksów, przeprowadzką rzadkich indeksów na bitmapowe przy migracji na enterprise, zmianą liczebności zbiorów danych i sposobem ich przechowywania( np.partycjonowanie tabel) - co może spowodować spory spadek wydajności... Lepiej jest więcej czasu poświęcić na rozpracowanie opornego zapytania niż umieszczać wskazówki w kodzie...
13.
Pogrzebmy w bebechach
select UPPER(username),
UPPER (osuser),
UPPER (program),
UPPER( machine)
into vc_UserName, vc_OSUser, vc_Program, vc_Machine
from v$session
where sid =
USERENV('sid');
Staranie się, aby unikać odwołań do tabeli słownikowych, a jeśli się tego nie uda to takowe wywołania wsadzić do osobnego pakietu i korzystać tylko i wyłącznie z funkcji pakietowych... Tak samo w przypadku pakietów systemowych - wywołania należy opakować
14.
Uprawnienia
GRANT SELECT,
INSERT,
DELETE,
UPDATE on fk.tbl_faktury
TO PANI_BASIA;
GRANT SELECT ON fk.tbl_faktury
TO PANI_JOLA.
Wszelakie uprawnienia do obiektów bazodanowych rozdzielać wyłącznie za pomocą ról, użytkownikom nie wolno nadawać ról bezpośrednio, to prowadzi do trudnego do opanowania chaosu w kodzie. Bywają czasami pojętni użytkownicy piszący własne procedury, dla nich można zrobić wyjątek, dla pozostałych lamerów nie
15.
Przedrostki
select * from schemat.klienci... Stosowanie standaryzowanych przedrostków (tbl_, vw_, seq_, mv_, pdb_, pckg_ ) do obiektów baz danych - aby w wypadku choroby genialnego kodera lub błędów runtime dało się cokolwiek zrozumieć, co genialny twórca miał na myśli
16. Nadużywanie zapytań z dual. Widziałem złośliwy test:
CREATE TABLE DUAL
AS
SELECT *
FROM DUAL
UNION ALL
SELECT *
FROM DUAL
17. Używanie w kodzie funkcji
SYSDATE ( za wyjątkiem pieczątek czasowych), zamiast tego należy użyć parametrów