42.6. ТÑиггеÑнÑе ÑÑнкÑии на PL/Tcl
Ðа PL/Tcl можно напиÑаÑÑ ÑÑиггеÑнÑе ÑÑнкÑии. Postgres Pro ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ ÑÑнкÑиÑ, коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ ÐºÐ°Ðº ÑÑиггеÑнаÑ, бÑла обÑÑвлена как ÑÑнкÑÐ¸Ñ Ð±ÐµÐ· аÑгÑменÑов и возвÑаÑала Ñип trigger.
ÐнÑоÑмаÑÐ¸Ñ Ð¾Ñ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑа ÑÑиггеÑов пеÑедаÑÑÑÑ Ð² Ñело ÑÑнкÑии в ÑледÑÑÑÐ¸Ñ Ð¿ÐµÑеменнÑÑ :
$TG_nameÐÐ¼Ñ ÑÑиггеÑа из опеÑаÑоÑа
CREATE TRIGGER.$TG_relidÐденÑиÑикаÑÐ¾Ñ Ð¾Ð±ÑекÑа ÑаблиÑÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑой бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ ÑÑиггеÑÐ½Ð°Ñ ÑÑнкÑиÑ.
$TG_table_nameÐÐ¼Ñ ÑаблиÑÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑой бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ ÑÑиггеÑÐ½Ð°Ñ ÑÑнкÑиÑ.
$TG_table_schemaÐ¡Ñ ÐµÐ¼Ð° ÑаблиÑÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑой бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ ÑÑиггеÑÐ½Ð°Ñ ÑÑнкÑиÑ.
$TG_relattsСпиÑок ÑзÑка Tcl, ÑодеÑжаÑий имена ÑÑолбÑов ÑаблиÑÑ. РнаÑало ÑпиÑка добавлен пÑÑÑой ÑлеменÑ, поÑÑÐ¾Ð¼Ñ Ð¿Ñи поиÑке в ÑÑом ÑпиÑке имени ÑÑолбÑа Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑандаÑÑной в Tcl командÑ
lsearchбÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑÑн Ð½Ð¾Ð¼ÐµÑ ÑлеменÑа, наÑÐ¸Ð½Ð°Ñ Ñ 1, Ñак же, как нÑмеÑÑÑÑÑÑ ÑÑолбÑÑ Ð² Postgres Pro. (РпозиÑиÑÑ ÑдалÑннÑÑ ÑÑолбÑов Ñакже ÑодеÑжаÑÑÑ Ð¿ÑÑÑÑе ÑлеменÑÑ, Ñак ÑÑо нÑмеÑаÑÐ¸Ñ ÑледÑÑÑÐ¸Ñ Ð·Ð° ними аÑÑибÑÑов не наÑÑÑаеÑÑÑ.)$TG_whenСÑÑока
BEFORE,AFTERилиINSTEAD OF, в завиÑимоÑÑи Ð¾Ñ Ñипа ÑобÑÑÐ¸Ñ ÑÑиггеÑа.$TG_levelСÑÑока
ROWилиSTATEMENT, в завиÑимоÑÑи Ð¾Ñ ÑÑÐ¾Ð²Ð½Ñ ÑобÑÑÐ¸Ñ ÑÑиггеÑа.$TG_opСÑÑока
INSERT,UPDATE,DELETEилиTRUNCATE, в завиÑимоÑÑи Ð¾Ñ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ ÑобÑÑÐ¸Ñ ÑÑиггеÑа.$NEWÐÑÑоÑиаÑивнÑй маÑÑив, ÑодеÑжаÑий знаÑÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð¹ ÑÑÑоки ÑаблиÑÑ Ð´Ð»Ñ Ð´ÐµÐ¹ÑÑвий
INSERTилиUPDATE, либо пÑÑÑой маÑÑив длÑDELETE. ÐндекÑами в маÑÑиве ÑвлÑÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð° ÑÑолбÑов. СÑолбÑÑ Ñо знаÑениÑми NULL в нÑм оÑÑÑÑÑÑвÑÑÑ. ÐÐ»Ñ ÑÑиггеÑов ÑÑÐ¾Ð²Ð½Ñ Ð¾Ð¿ÐµÑаÑоÑа ÑÑÐ¾Ñ Ð¼Ð°ÑÑив не опÑеделÑеÑÑÑ.$OLDÐÑÑоÑиаÑивнÑй маÑÑив, ÑодеÑжаÑий знаÑÐµÐ½Ð¸Ñ ÑÑаÑой ÑÑÑоки ÑаблиÑÑ Ð´Ð»Ñ Ð´ÐµÐ¹ÑÑвий
UPDATEилиDELETE, либо пÑÑÑой маÑÑив длÑINSERT. ÐндекÑами в маÑÑиве ÑвлÑÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð° ÑÑолбÑов. СÑолбÑÑ Ñо знаÑениÑми NULL в нÑм оÑÑÑÑÑÑвÑÑÑ. ÐÐ»Ñ ÑÑиггеÑов ÑÑÐ¾Ð²Ð½Ñ Ð¾Ð¿ÐµÑаÑоÑа ÑÑÐ¾Ñ Ð¼Ð°ÑÑив не опÑеделÑеÑÑÑ.$argsСпиÑок на ÑзÑке Tcl аÑгÑменÑов ÑÑнкÑии, заданнÑÑ Ð² опеÑаÑоÑе
CREATE TRIGGER. ÐÑи аÑгÑменÑÑ Ñакже доÑÑÑÐ¿Ð½Ñ Ð¿Ð¾Ð´ обознаÑениÑми$1...$в Ñеле ÑÑнкÑии.n
ÐозвÑаÑаемÑм знаÑением ÑÑиггеÑной ÑÑнкÑии Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑока OK или SKIP либо ÑпиÑок Ð¿Ð°Ñ Ð¸Ð¼Ñ ÑÑолбÑа/знаÑение. ÐÑли возвÑаÑаеÑÑÑ Ð·Ð½Ð°Ñение OK, опеÑаÑÐ¸Ñ (INSERT/UPDATE/DELETE), коÑоÑÐ°Ñ Ð¿Ñивела к ÑÑабаÑÑÐ²Ð°Ð½Ð¸Ñ ÑÑиггеÑа, вÑполнÑеÑÑÑ Ð½Ð¾ÑмалÑно. ÐнаÑение SKIP ÑказÑÐ²Ð°ÐµÑ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑÑ ÑÑиггеÑов пÑоÑÑо пÑопÑÑÑиÑÑ ÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ñ ÑекÑÑей ÑÑÑокой даннÑÑ
. ÐÑли возвÑаÑаеÑÑÑ ÑпиÑок, ÑеÑез него PL/Tcl пеÑедаÑÑ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑÑ ÑÑиггеÑов изменÑннÑÑ ÑÑÑокÑ; ÑодеÑжимое изменÑнной ÑÑÑоки задаÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ и знаÑениÑми ÑÑолбÑов в ÑпиÑке. ÐÑе ÑÑолбÑÑ, не пеÑеÑиÑленнÑе в ÑÑом ÑпиÑке, полÑÑаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL. ÐозвÑаÑаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑннÑÑ ÑÑÑÐ¾ÐºÑ Ð¸Ð¼ÐµÐµÑ ÑмÑÑл ÑолÑко Ð´Ð»Ñ ÑÑиггеÑов ÑÑÐ¾Ð²Ð½Ñ ÑÑÑоки Ñ Ð¿Ð¾ÑÑдком BEFORE команд INSERT и UPDATE, в коÑоÑÑÑ
вмеÑÑо заданной в $NEW бÑÐ´ÐµÑ Ð·Ð°Ð¿Ð¸ÑÑваÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÐ½Ð½Ð°Ñ ÑÑÑока; либо Ñ Ð¿Ð¾ÑÑдком INSTEAD OF команд INSERT и UPDATE, в коÑоÑÑÑ
возвÑаÑÐ°ÐµÐ¼Ð°Ñ ÑÑÑока ÑлÑÐ¶Ð¸Ñ Ð¸ÑÑ
однÑми даннÑми Ð´Ð»Ñ Ð¿Ñедложений INSERT RETURNING или UPDATE RETURNING. Ð ÑÑиггеÑаÑ
ÑÑÐ¾Ð²Ð½Ñ ÑÑÑоки Ñ Ð¿Ð¾ÑÑдком BEFORE или INSTEAD OF ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ DELETE возвÑÐ°Ñ Ð¸Ð·Ð¼ÐµÐ½Ñнной ÑÑÑоки воÑпÑинимаеÑÑÑ Ñак же, как и возвÑÐ°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ OK, Ñо еÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð²ÑполнÑеÑÑÑ. ÐÐ»Ñ Ð²ÑеÑ
оÑÑалÑнÑÑ
Ñипов ÑÑиггеÑов возвÑаÑаемое знаÑение игноÑиÑÑеÑÑÑ.
ÐодÑказка
СпиÑок ÑезÑлÑÑаÑов можно ÑоздаÑÑ Ð¸Ð· изменÑнного коÑÑежа, пÑедÑÑавленного в виде маÑÑива, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ array get ÑзÑка Tcl.
СледÑÑÑий неболÑÑой пÑÐ¸Ð¼ÐµÑ Ð¿Ð¾ÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÑÑиггеÑнÑÑ ÑÑнкÑиÑ, коÑоÑÐ°Ñ Ð²ÐµÐ´ÑÑ Ð² ÑаблиÑе ÑелоÑиÑленнÑй ÑÑÑÑÑик ÑиÑла изменений, вÑполненнÑÑ Ð² ÑÑÑоке. ÐÐ»Ñ Ð½Ð¾Ð²ÑÑ ÑÑÑок ÑÑÑÑÑик иниÑиализиÑÑеÑÑÑ Ð½ÑлевÑм знаÑением, а заÑем ÑвелиÑиваеÑÑÑ Ð½Ð° единиÑÑ Ð¿Ñи каждом изменении.
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
switch $TG_op {
INSERT {
set NEW($1) 0
}
UPDATE {
set NEW($1) $OLD($1)
incr NEW($1)
}
default {
return OK
}
}
return [array get NEW]
$$ LANGUAGE pltcl;
CREATE TABLE mytab (num integer, description text, modcnt integer);
CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');ÐамеÑÑÑе, ÑÑо Ñама ÑÑиггеÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½Ðµ Ð·Ð½Ð°ÐµÑ Ð¸Ð¼ÐµÐ½Ð¸ ÑÑолбÑа; оно пеÑедаÑÑÑÑ Ð² аÑгÑменÑÐ°Ñ ÑÑиггеÑа. ÐÑо позволÑÐµÑ Ð¿ÑименÑÑÑ ÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ ÑазлиÑнÑÑ ÑаблиÑ.