F.52. spi
- F.52.1. refint â ÑÑнкÑии Ð´Ð»Ñ ÑеализаÑии ÑÑÑлоÑной ÑелоÑÑноÑÑи
- F.52.2. timetravel â ÑÑнкÑии Ð´Ð»Ñ ÑеализаÑии пеÑемеÑений во вÑемени
- F.52.3. autoinc â ÑÑнкÑии Ð´Ð»Ñ Ð°Ð²ÑоÑвелиÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ¹
- F.52.4. insert_username â ÑÑнкÑии Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ, вноÑÑÑего изменениÑ
- F.52.5. moddatetime â ÑÑнкÑии Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð²Ñемени поÑледнего изменениÑ
- F.52.2. timetravel â ÑÑнкÑии Ð´Ð»Ñ ÑеализаÑии пеÑемеÑений во вÑемени
ÐодÑÐ»Ñ spi пÑедоÑÑавлÑÐµÑ Ð½ÐµÑколÑко ÑабоÑÐ¸Ñ Ð¿ÑимеÑов иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐнÑеÑÑейÑа пÑогÑаммиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑеÑвеÑа (Server Programming Interface, SPI) и ÑÑиггеÑов. ХоÑÑ ÑÑи ÑÑнкÑии имеÑÑ Ð½ÐµÐºÐ¾ÑоÑÑÑ ÑенноÑÑÑ Ñами по Ñебе, они еÑÑ Ð±Ð¾Ð»ÐµÐµ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ ÐºÐ°Ðº загоÑовки, коÑоÑÑе можно пÑиÑпоÑобиÑÑ Ð¿Ð¾Ð´ ÑобÑÑвеннÑе нÑждÑ. ÐÑи ÑÑнкÑии доÑÑаÑоÑно обÑие, ÑÑÐ¾Ð±Ñ ÑабоÑаÑÑ Ñ Ð»Ñбой ÑаблиÑей, но Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ñвно ÑказаÑÑ Ð¸Ð¼ÐµÐ½Ð° ÑаблиÑÑ Ð¸ полей (как опиÑано ниже) пÑи Ñоздании ÑÑиггеÑа.
ÐÐ°Ð¶Ð´Ð°Ñ Ð³ÑÑппа ÑÑнкÑий, опиÑÐ°Ð½Ð½Ð°Ñ Ð½Ð¸Ð¶Ðµ, пÑедÑÑавлена в виде оÑделÑно ÑÑÑанавливаемого ÑаÑÑиÑениÑ.
F.52.1. refint â ÑÑнкÑии Ð´Ð»Ñ ÑеализаÑии ÑÑÑлоÑной ÑелоÑÑноÑÑи
ФÑнкÑии check_primary_key() и check_foreign_key() пÑименÑÑÑÑÑ Ð´Ð»Ñ Ð¿ÑовеÑки огÑаниÑений внеÑниÑ
клÑÑей. (ÐÑа ÑÑнкÑионалÑноÑÑÑ Ñже давно вÑÑеÑнена вÑÑÑоеннÑм меÑ
анизмом внеÑниÑ
клÑÑей, но ÑÑÐ¾Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð²ÑÑ ÐµÑÑ Ð¿Ð¾Ð»ÐµÐ·ÐµÐ½ в каÑеÑÑве пÑимеÑа.)
ФÑнкÑÐ¸Ñ check_primary_key() пÑовеÑÑÐµÑ ÑÑÑлаÑÑÑÑÑÑ ÑаблиÑÑ. ЧÑÐ¾Ð±Ñ Ð²Ð¾ÑполÑзоваÑÑÑÑ ÐµÐ¹, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE INSERT OR UPDATE Ñ ÑÑой ÑÑнкÑией Ð´Ð»Ñ ÑаблиÑÑ, ÑÑÑлаÑÑейÑÑ Ð½Ð° дÑÑгÑÑ. УкажиÑе в аÑгÑменÑаÑ
ÑÑиггеÑа: имена ÑÑолбÑов ÑÑÑлаÑÑейÑÑ ÑаблиÑÑ, обÑазÑÑÑиÑ
внеÑний клÑÑ, Ð¸Ð¼Ñ Ñелевой ÑаблиÑÑ Ð¸ имена ÑÑолбÑов в ней, обÑазÑÑÑиÑ
пеÑвиÑнÑй/ÑникалÑнÑй клÑÑ. ЧÑÐ¾Ð±Ñ ÐºÐ¾Ð½ÑÑолиÑоваÑÑ Ð½ÐµÑколÑко внеÑниÑ
клÑÑей, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ñакой ÑÑÑлки.
ФÑнкÑÐ¸Ñ check_foreign_key() пÑовеÑÑÐµÑ ÑелевÑÑ ÑаблиÑÑ. ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE DELETE OR UPDATE Ñ ÑÑой ÑÑнкÑией Ð´Ð»Ñ ÑаблиÑÑ, на коÑоÑÑÑ ÑÑÑлаÑÑÑÑ Ð´ÑÑгие. УкажиÑе в аÑгÑменÑаÑ
ÑÑиггеÑа: ÑиÑло ÑÑÑлаÑÑиÑ
ÑÑ ÑаблиÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° вÑполниÑÑ Ð¿ÑовеÑки, дейÑÑвие в ÑлÑÑае обнаÑÑÐ¶ÐµÐ½Ð¸Ñ ÑÑÑлаÑÑегоÑÑ ÐºÐ»ÑÑа (cascade â ÑдалиÑÑ ÑÑÑлаÑÑÑÑÑÑ ÑÑÑокÑ, restrict â пÑеÑваÑÑ ÑÑанзакÑиÑ, setnull â ÑÑÑановиÑÑ Ð² ÑÑÑлаÑÑиÑ
ÑÑ Ð¿Ð¾Ð»ÑÑ
знаÑÐµÐ½Ð¸Ñ NULL), имена ÑÑолбÑов Ñелевой ÑаблиÑÑ, обÑазÑÑÑиÑ
пеÑвиÑнÑй/ÑникалÑнÑй клÑÑ, а заÑем имена ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ ÑÑолбÑов (в колиÑеÑÑве, задаваемом пеÑвÑм аÑгÑменÑом). ÐамеÑÑÑе, ÑÑо Ð¿Ð¾Ð»Ñ Ð¿ÐµÑвиÑнÑÑ
/ÑникалÑнÑÑ
ÑÑолбÑов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð¼ÐµÑÑ Ð¿Ð¾Ð¼ÐµÑÐºÑ NOT NULL и по ним должен бÑÑÑ Ñоздан ÑникалÑнÑй индекÑ.
ÐÑимеÑÑ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ð² refint.example.
F.52.2. timetravel â ÑÑнкÑии Ð´Ð»Ñ ÑеализаÑии пеÑемеÑений во вÑемени
РдалÑком пÑоÑлом в Postgres Pro бÑла вÑÑÑÐ¾ÐµÐ½Ð½Ð°Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¿ÐµÑемеÑений во вÑемени, Ð´Ð»Ñ ÐºÐ¾ÑоÑой ÑикÑиÑовалоÑÑ Ð²ÑÐµÐ¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ коÑÑежа. ÐÑи ÑÑнкÑии позволÑÑÑ ÐµÑ Ð¸Ð¼Ð¸ÑиÑоваÑÑ. ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ Ð¸Ñ
, Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð² ÑаблиÑÑ Ð´Ð²Ð° ÑÑолбÑа Ñипа abstime, в коÑоÑÑÑ
бÑÐ´ÐµÑ Ñ
ÑаниÑÑÑÑ Ð´Ð°Ñа/вÑемÑ, когда коÑÑеж бÑл вÑÑавлен (start_date) и когда изменÑн/ÑдалÑн (stop_date):
CREATE TABLE mytab (
... ...
start_date abstime,
stop_date abstime
... ...
);ÐÑи ÑÑолбÑÑ Ð¼Ð¾Ð³ÑÑ Ð½Ð°Ð·ÑваÑÑÑÑ ÐºÐ°Ðº Ñгодно, но в данном опиÑании они назÑваÑÑÑÑ start_date и stop_date.
Ðогда вÑÑавлÑеÑÑÑ Ð½Ð¾Ð²Ð°Ñ ÑÑÑока, в start_date обÑÑно ÑÑÑанавливаеÑÑÑ ÑекÑÑее вÑемÑ, а в stop_date â infinity (беÑконеÑноÑÑÑ). ТÑÐ¸Ð³Ð³ÐµÑ Ð°Ð²ÑомаÑиÑеÑки подÑÑÐ°Ð²Ð¸Ñ ÑÑи знаÑениÑ, еÑли добавлÑÐµÐ¼Ð°Ñ ÑÑÑока ÑодеÑÐ¶Ð¸Ñ NULL в ÑÑиÑ
ÑÑолбÑаÑ
. ÐбÑÑно не NULL в ÑÑиÑ
ÑÑолбÑаÑ
Ð¼Ð¾Ð¶ÐµÑ Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ ÑолÑко пÑи загÑÑзке в Ð±Ð°Ð·Ñ Ð²ÑгÑÑженнÑÑ
даннÑÑ
.
ÐоÑÑежи, в коÑоÑÑÑ
поле stop_date Ñавно infinity, ÑÑиÑаÑÑÑÑ Â«Ð°ÐºÑÑалÑнÑми ÑейÑаÑ» и могÑÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ. ÐоÑÑежи Ñ Ð¾Ð¿ÑеделÑнной даÑой stop_date болÑÑе не могÑÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ â ÑÑÐ¸Ð³Ð³ÐµÑ Ð±ÑÐ´ÐµÑ Ð¿ÑепÑÑÑÑвоваÑÑ ÑÑомÑ. (ÐÑли вам нÑжно ÑделаÑÑ ÑÑо, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе оÑклÑÑиÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ Ð²Ñемени как показано ниже.)
ÐÑли коÑÑеж ÑвлÑеÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑемÑм, пÑи модиÑикаÑии в нÑм менÑеÑÑÑ ÑолÑко stop_date (на ÑекÑÑее вÑемÑ), но в ÑаблиÑÑ Ð²ÑÑавлÑеÑÑÑ Ð½Ð¾Ð²Ñй коÑÑеж Ñ Ð¼Ð¾Ð´Ð¸ÑиÑиÑованнÑми даннÑми. Рполе start_date в ÑÑом новом коÑÑеже запиÑÑваеÑÑÑ ÑекÑÑее вÑемÑ, а в stop_date запиÑÑваеÑÑÑ infinity.
ÐÑи Ñдалении коÑÑеж на Ñамом деле не ÑдалÑеÑÑÑ; в нÑм ÑолÑко запиÑÑваеÑÑÑ ÑекÑÑее вÑÐµÐ¼Ñ Ð² stop_date.
ЧÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑоÑиÑÑ ÐºÐ¾ÑÑежи «акÑÑалÑнÑе ÑейÑаÑ», добавÑÑе stop_date = 'infinity' в ÑÑловие WHERE ваÑего запÑоÑа. (Ðозможно, Ð²Ñ Ð·Ð°Ñ
оÑиÑе завеÑнÑÑÑ ÑÑо ÑÑловие в пÑедÑÑавление.) ÐналогиÑнÑм обÑазом Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе запÑаÑиваÑÑ ÐºÐ¾ÑÑежи, коÑоÑÑе бÑли акÑÑалÑÐ½Ñ Ð² лÑбой Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð² пÑоÑлом, задав подÑ
одÑÑие ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð´Ð»Ñ start_date и stop_date.
ФÑнкÑÐ¸Ñ timetravel() ÑеализÑÐµÑ ÐºÐ¾Ð´ ÑнивеÑÑалÑного ÑÑиггеÑа, поддеÑживаÑÑего ÑÑо поведение. ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE INSERT OR UPDATE OR DELETE Ñ ÑÑой ÑÑнкÑией Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑаблиÑÑ, пеÑемеÑаÑÑейÑÑ Ð²Ð¾ вÑемени. ÐеÑедайÑе ÑÑиггеÑÑ Ð´Ð²Ð° аÑгÑменÑа: ÑакÑиÑеÑкие имена ÑÑолбÑов start_date и stop_date. ÐÑ Ñакже можеÑе дополниÑелÑно пеÑедаÑÑ Ð¾Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ до ÑÑÑÑ
аÑгÑменÑов, задаÑÑиÑ
имена ÑÑолбÑов Ñипа text. ÐаннÑй ÑÑÐ¸Ð³Ð³ÐµÑ ÑоÑ
ÑÐ°Ð½Ð¸Ñ Ð¸Ð¼Ñ ÑекÑÑего полÑзоваÑÐµÐ»Ñ Ð² пеÑвÑй из ÑÑиÑ
ÑÑолбÑов пÑи INSERT, во вÑоÑой â пÑи UPDATE, и в ÑÑеÑий â пÑи DELETE.
ФÑнкÑÐ¸Ñ set_timetravel() позволÑÐµÑ Ð²ÐºÐ»ÑÑиÑÑ Ð¸Ð»Ð¸ оÑклÑÑиÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ Ð²Ñемени Ð´Ð»Ñ ÑаблиÑÑ. ÐÑзов set_timetravel('mytab', 1) вклÑÑÐ°ÐµÑ Ð¼Ð°ÑÐ¸Ð½Ñ Ð²Ñемени Ð´Ð»Ñ ÑаблиÑÑ mytab, а set_timetravel('mytab', 0) â оÑклÑÑÐ°ÐµÑ ÐµÑ Ð´Ð»Ñ ÑаблиÑÑ mytab. РобоиÑ
ÑлÑÑаÑÑ
возвÑаÑаеÑÑÑ Ð¿Ñежнее ÑоÑÑоÑние. Ðогда маÑина вÑемени вÑклÑÑена, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе Ñвободно модиÑиÑиÑоваÑÑ ÑÑолбÑÑ start_date и stop_date. ÐамеÑÑÑе, ÑÑо ÑоÑÑоÑние акÑивноÑÑи маÑÐ¸Ð½Ñ ÑвлÑеÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм Ð´Ð»Ñ ÑекÑÑего ÑеанÑа Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
â в новÑÑ
ÑеанÑаÑ
маÑина вÑемени вÑегда вклÑÑена Ð´Ð»Ñ Ð²ÑеÑ
ÑаблиÑ.
ФÑнкÑÐ¸Ñ get_timetravel() возвÑаÑÐ°ÐµÑ ÑоÑÑоÑние пеÑемеÑÐµÐ½Ð¸Ñ Ð²Ð¾ вÑемени Ð´Ð»Ñ ÑаблиÑÑ, не менÑÑ ÐµÐ³Ð¾.
ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑиведÑн в timetravel.example.
F.52.3. autoinc â ÑÑнкÑии Ð´Ð»Ñ Ð°Ð²ÑоÑвелиÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ¹
ФÑнкÑÐ¸Ñ autoinc() ÑеализÑÐµÑ ÐºÐ¾Ð´ ÑÑиггеÑа, ÑоÑ
ÑанÑÑÑего ÑледÑÑÑее знаÑение поÑледоваÑелÑноÑÑи в ÑелоÑиÑленном поле. ÐÑо в некоÑоÑой ÑÑепени пеÑеÑекаеÑÑÑ Ñо вÑÑÑоенной ÑÑнкÑионалÑноÑÑÑÑ ÑÑолбÑа «serial», но еÑÑÑ Ð¸ оÑлиÑиÑ: autoinc() пÑепÑÑÑÑвÑÐµÑ Ð¿Ð¾Ð¿ÑÑкам вÑÑавиÑÑ Ð´ÑÑгое знаÑение Ð¿Ð¾Ð»Ñ Ð¿Ñи добавлении ÑÑÑок и Ð¼Ð¾Ð¶ÐµÑ ÑвелиÑиваÑÑ Ð·Ð½Ð°Ñение Ð¿Ð¾Ð»Ñ Ð¿Ñи изменениÑÑ
.
ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE INSERT (или BEFORE INSERT OR UPDATE) Ñ ÑÑой ÑÑнкÑией. ÐеÑедайÑе ÑÑиггеÑÑ Ð´Ð²Ð° аÑгÑменÑа: Ð¸Ð¼Ñ ÑелоÑиÑленного ÑÑолбÑа, коÑоÑÑй бÑÐ´ÐµÑ Ð¼ÐµÐ½ÑÑÑÑÑ, и Ð¸Ð¼Ñ Ð¾Ð±ÑекÑа поÑледоваÑелÑноÑÑи, коÑоÑÑй бÑÐ´ÐµÑ Ð¿Ð¾ÑÑавлÑÑÑ Ð·Ð½Ð°ÑениÑ. (ÐообÑе Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе задаÑÑ Ð»Ñбое ÑиÑло Ð¿Ð°Ñ ÑакиÑ
имÑн, еÑли Ñ
оÑиÑе поддеÑживаÑÑ Ð½ÐµÑколÑко авÑоÑвелиÑиваÑÑиÑ
ÑÑ ÑÑолбÑов.)
ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑиведÑн в autoinc.example.
F.52.4. insert_username â ÑÑнкÑии Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ, вноÑÑÑего изменениÑ
ФÑнкÑÐ¸Ñ insert_username() ÑеализÑÐµÑ ÐºÐ¾Ð´ ÑÑиггеÑа, ÑоÑ
ÑанÑÑÑего Ð¸Ð¼Ñ ÑекÑÑего полÑзоваÑÐµÐ»Ñ Ð² ÑекÑÑовом поле. ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾ Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ, изменивÑего конкÑеÑнÑÑ ÑÑÑÐ¾ÐºÑ ÑаблиÑÑ Ð¿Ð¾Ñледним.
ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE INSERT и/или UPDATE Ñ ÑÑой ÑÑнкÑией. ÐеÑедайÑе ÑÑиггеÑÑ Ð¾Ð´Ð¸Ð½ аÑгÑменÑ: Ð¸Ð¼Ñ Ñелевого ÑекÑÑового ÑÑолбÑа.
ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑиведÑн в insert_username.example.
F.52.5. moddatetime â ÑÑнкÑии Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð²Ñемени поÑледнего изменениÑ
ФÑнкÑÐ¸Ñ moddatetime() ÑеализÑÐµÑ ÐºÐ¾Ð´ ÑÑиггеÑа, ÑоÑ
ÑанÑÑÑего ÑекÑÑее вÑÐµÐ¼Ñ Ð² поле Ñипа timestamp. ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾ Ð´Ð»Ñ Ð¾ÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð²Ñемени поÑледней модиÑикаÑии конкÑеÑной ÑÑÑоки ÑаблиÑÑ.
ЧÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ, ÑоздайÑе ÑÑÐ¸Ð³Ð³ÐµÑ BEFORE UPDATE Ñ ÑÑой ÑÑнкÑией. ÐеÑедайÑе ÑÑиггеÑÑ Ð¾Ð´Ð¸Ð½ аÑгÑменÑ: Ð¸Ð¼Ñ Ñелевого ÑÑолбÑа. СÑÐ¾Ð»Ð±ÐµÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ имеÑÑ Ñип timestamp или timestamp with time zone.
ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑиведÑн в moddatetime.example.