1. Modyfikator result_cache dla funkcji niedeterministycznych przekształca je na deterministyczne
Funkcja deterministyczna jest to funkcja zwracająca dla takiego samego zbioru parametrów identyczny wynik. Deterministyczności wymaga sie od wyrażeń w indeksach funkcyjnych i polach wyliczeniowych dla tabel.. Deterministyczność wyklucza użycie funkcji SYSDATE, funkcji losowych...
Rozważmy poniższy przykład:
Skompilujmy poniższą funkcję:
CREATE OR REPLACE FUNCTION Fdb_Test RETURN DATE
RESULT_CACHE
IS
BEGIN
RETURN SYSDATE;
END;
Następnie wywołajmy pięć razy w odstępach kilkusekundowych:
SELECT Fdb_Test FROM DUAL
O ile bufor dla result cache jest nieprzepełniony, to funkcja zwróci nam za każdym wywołaniem taką samą wartość. Poniższe sprawdzenie pokaże czterokrotne użycie bufora(za pierwszym razem rzeczywiście wywoła się SYSDATE):
SELECT SCAN_COUNT
FROM V$RESULT_CACHE_OBJECTS WHERE NAMESPACE ='PLSQL' AND NAME LIKE '%FDB_TEST%'
2. Struktury zakotwiczone %ROWTYPE zapewniają uproszczenie wstawiania..
I z reguły jest to prawda
Stwórzmy tabelę:
CREATE TABLE TBL_TEST
(ID NUMBER(4),
OPIS VARCHAR2(50 CHAR)
)
Można wówczas dokonać wstawiania w bardzo elegancki sposób bez podawania listy kolumn...
DECLARE
vr_Test TBL_TEST%ROWTYPE;
BEGIN
vr_Test.ID := 1;
vr_Test.Opis := 'Opis';
INSERT INTO TBL_TEST VALUES vr_Test;
COMMIT;
END;Zakotwiczenie przy wstawianiu będzie dalej działało przy dodaniu nowych pól, chyba, że to będą pola obliczeniowe..
Po dodaniu formuły
ALTER TABLE TBL_TEST ADD FORMULA VARCHAR2(100 CHAR) GENERATED ALWAYS AS ( TO_CHAR(ID) || ' ' || OPIS)
przy próbie wykonania powyższego bloku pojawi się komunikat
ORA-54013: INSERT operation disallowed on virtual columns
Szkoda, że obie możliwości nie mogą działać jednocześnie (:
3, Triggery DML blokują jedynie operacje DML
Jeśli chcemy zablokować w sposób dynamiczny np. usuwanie z tabel, to nie można użytkownikom końcowym nadawać żadnych uprawnień DDL do tabeli..
Poniższy trigger
CREATE OR REPLACE TRIGGER .TRG_TBL_TEST__NO_DELETE
BEFORE DELETE
ON TBL_TEST
--w celu lepszej wydajności powinien to być triger on statement, a nie FOR EACH ROW
BEGIN
IF EXTRACT( HOUR FROM LOCALTIMESTAMP ) BETWEEN 8 AND 18 THEN
RAISE_APPLICATION_ERROR (- 20100, 'Usuwanie w godzinach pracy z tabeli jest niedozwolone' );
END IF;
END TRG_TBL_TEST__NO_DELETE;
nie zabezpieczy przed instrukcją DDL
TRUNCATE TABLE TBL_TEST
jeśli użytkownik końcowy posiadać będzie bezpośrednio nadane uprawnienie ALTER TABLE