Volání ověřovacích pravidel a triggerů v databázích

Jistě jste si již zkusili nastavit ověřovací pravidla pro položky a věty (Field Validation Rule a Record Validation Rule), nastavit primární a kandidátní klíče a naprogramovat své triggery. Možná vám ale uniklo několik důležitých informací.

Používání OLDVAL a GETFLDSTATE

V ověřovacích pravidlech i v triggerech lze používat funkce OLDVAL() a GETFLDSTATE() bez ohledu na to, zda je nastaven nějaký režim bufferování nebo ne. Takže lze například snadno zajistit, aby se třeba omylem nezvýšila cena výrobku o více než 10%:
IF NOT ISNULL(OLDVAL("cena")) AND cena>1.1*OLDVAL("cena")
   =MESSAGEBOX("Maximální zvýšení ceny je 10%")
   RETURN .F.
ENDIF
Všimněte si testu na NULL - pro nově přidané věty má totiž položka hodnotu NULL. Kdy se bude trigger nebo ověřovací pravidlo volat (a zda je tedy nutné testovat i hodnotu cena=0 po přidání věty) závisí na režimu bufferování a na tom, zda se jedná o tabulku nebo pohled.

Okamžik volání ověřovacích pravidel a triggerů

Pokusil jsem se sestavit tabulku popisující odlišnosti v okamžiku volání ověřovacích pravidel, testů na primární/kandidátní klíče a triggerů podle toho, zda se jedná o tabulku nebo pohled v závislosti na režimu bufferování. Domnívám se, že pokud si ji prostudujete, určitě budete překvapeni rozdíly v okamžicích volání, je-li nastaveno bufferování.

NO BUFFERING DBF ROW/TABLE BUFF VIEW ROW BUFF VIEW TABLE BUFF
APPEND BLANK ... Field Validation
Record Validation
Primary Key Test
Insert Trigger
Nic Nic Nic
REPLACE Field Validation
Record Validation
Primary Key Test
Update Trigger
Field Validation View Field Validation View Field Validation
INSERT INTO ... Field Validation
Record Validation
Primary Key Test
Insert Trigger
Field Validation View Field Validation View Field Validation
DELETE Delete Trigger Nic Nic Nic
RECALL Field Validation
Record Validation
Primary Key Test
Insert Trigger
Nic Nic Nic
SKIP 1 Nic Record Validation
Primary Key Test…
Trigger
[View Field Validation,
pokud předcházel
RECALL]
Field Validation
Record Validation
Primary Key Test
Insert Trigger
[View Field
Validation, pokud
předcházel RECALL]
TABLE-UPDATE * Record Validation
Primary Key Test…
Trigger
Field Validation
Record Validation
Primary Key Test
Insert Trigger
Field Validation
Record Validation
Primary Key Test
Insert Trigger
USE Nic je-li potřeba:
Record Validation
Primary Key Test
Pokud ROW:… Trigger
[View Field Validation,
je-li třeba]
Field Validation
Record Validation
Primary Key Test
Nic

Přeskočení volání triggeru

Někdy je třeba na "chvíli" vypnout trigger, protože potřebujeme provést činnost, která by s triggery trvala příliš dlouho, a přitom víme, že nejsou v daném okamžiku potřeba. Postup je jednoduchý (snad až příliš - nezapomeňte vrátit nastavení triggeru zpátky!):
lcTriggerVal = DBGETPROP("MyTable", "Table", "DeleteTrigger")
* Probíhá zpracování bez triggeru ...
CREATE TRIGGER ON MyTable FOR DELETE AS (lctriggerVal)


Projekty a databáze

Pokud máme v projektu rozbalenou hierarchii databáze, je tato DBC automaticky otevřena při otevření projektu (podle nastavení SET EXCLUSIVE jako EXCL nebo SHARED) a nefunguje na ni CLOSE DATABASE ALL! (udělá jenom SET DATABASE TO, ale databáze zůstane dál otevřená). Vede to k problémům, obzvláště pokud s ní pracuje (nebo spíše se pokouší pracovat :-) ) více programátorů.

Zdraví vás
Milan Kosina, kosina@vol.cz