40.8. СообÑÐµÐ½Ð¸Ñ Ð¸ оÑибки
40.8.1. ÐÑвод ÑообÑений и оÑибок
Ðоманда RAISE пÑедназнаÑена Ð´Ð»Ñ Ð²Ñвода ÑообÑений и вÑзова оÑибок.
RAISE [ÑÑовенÑ] 'ÑоÑмаÑ' [,вÑÑажение[, ... ]] [ USINGпаÑамеÑÑ=знаÑение[, ... ] ]; RAISE [ÑÑовенÑ]имÑ_ÑÑловиÑ[ USINGпаÑамеÑÑ=вÑÑажение[, ... ] ]; RAISE [ÑÑовенÑ] SQLSTATE 'sqlstate' [ USINGпаÑамеÑÑ=вÑÑажение[, ... ] ]; RAISE [ÑÑовенÑ] USINGпаÑамеÑÑ=вÑÑажение[, ... ]; RAISE ;
ÑÑÐ¾Ð²ÐµÐ½Ñ Ð·Ð°Ð´Ð°ÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ Ð²Ð°Ð¶Ð½Ð¾ÑÑи оÑибки. ÐозможнÑе знаÑениÑ: DEBUG, LOG, INFO, NOTICE, WARNING и EXCEPTION. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¸ÑполÑзÑеÑÑÑ EXCEPTION. EXCEPTION вÑзÑÐ²Ð°ÐµÑ Ð¾ÑÐ¸Ð±ÐºÑ (ÑÑо обÑÑно пÑеÑÑÐ²Ð°ÐµÑ ÑекÑÑÑÑ ÑÑанзакÑиÑ), оÑÑалÑнÑе знаÑÐµÐ½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ ÑолÑко генеÑиÑÑÑÑ ÑообÑÐµÐ½Ð¸Ñ Ñ ÑазлиÑнÑми ÑÑовнÑми пÑиоÑиÑеÑа. ÐÑдÑÑ Ð»Ð¸ ÑообÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð½ÐºÑеÑного пÑиоÑиÑеÑа пеÑÐµÐ´Ð°Ð½Ñ ÐºÐ»Ð¸ÐµÐ½ÑÑ Ð¸Ð»Ð¸ запиÑÐ°Ð½Ñ Ð² жÑÑнал ÑеÑвеÑа, или и Ñо, и дÑÑгое, завиÑÐ¸Ñ Ð¾Ñ ÐºÐ¾Ð½ÑигÑÑаÑионнÑÑ
пеÑеменнÑÑ
log_min_messages и client_min_messages. Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº Ðлаве 18.
ÐоÑле ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ ÑÑовнÑ, еÑли оно еÑÑÑ, можно задаÑÑ ÑÑÑÐ¾ÐºÑ ÑоÑмаÑа (ÑÑо должна бÑÑÑ Ð¿ÑоÑÑÐ°Ñ ÑÑÑÐ¾ÐºÐ¾Ð²Ð°Ñ ÐºÐ¾Ð½ÑÑанÑа, не вÑÑажение). СÑÑока ÑоÑмаÑа опÑеделÑÐµÑ Ð²Ð¸Ð´ ÑекÑÑа об оÑибке, коÑоÑÑй бÑÐ´ÐµÑ Ð²Ñдан. Ðа ÑÑÑокой ÑоÑмаÑа могÑÑ ÑледоваÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð°ÑгÑменÑов, коÑоÑÑе бÑдÑÑ Ð²ÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð² ÑообÑение. ÐнÑÑÑи ÑÑÑоки ÑоÑмаÑа знак % заменÑеÑÑÑ ÑÑÑоковÑм пÑедÑÑавлением знаÑÐµÐ½Ð¸Ñ Ð¾ÑеÑедного аÑгÑменÑа. ЧÑÐ¾Ð±Ñ Ð²ÑдаÑÑ Ñимвол % бÑквалÑно, пÑодÑблиÑÑйÑе его (как %%). ЧиÑло аÑгÑменÑов должно ÑовпадаÑÑ Ñ ÑиÑлом меÑÑозаполниÑелей % в ÑÑÑоке ÑоÑмаÑа, инаÑе пÑи компилÑÑии ÑÑнкÑии Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÐµÑ Ð¾Ñибка.
Ð ÑледÑÑÑем пÑимеÑе Ñимвол % бÑÐ´ÐµÑ Ð·Ð°Ð¼ÐµÐ½Ñн на знаÑение v_job_id:
RAISE NOTICE 'ÐÑзов ÑÑнкÑии cs_create_job(%)', v_job_id;
ÐÑи помоÑи USING и поÑледÑÑÑиÑ
ÑлеменÑов паÑамеÑÑ = вÑÑажение можно добавиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ðº оÑÑÑÑÑ Ð¾Ð± оÑибке. ÐÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑедÑÑавлÑÑÑ Ñобой ÑÑÑоковÑе вÑÑажениÑ. ÐозможнÑе клÑÑевÑе Ñлова Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑа ÑледÑÑÑие:
MESSAGEУÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑекÑÑ ÑообÑÐµÐ½Ð¸Ñ Ð¾Ð± оÑибке. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ, еÑли в команде
RAISEпÑиÑÑÑÑÑвÑеÑÑоÑмаÑпеÑедUSING.DETAILÐÑедоÑÑавлÑÐµÑ Ð´ÐµÑалÑное ÑообÑение об оÑибке.
HINTÐÑедоÑÑавлÑÐµÑ Ð¿Ð¾Ð´ÑÐºÐ°Ð·ÐºÑ Ð¿Ð¾ вÑзванной оÑибке.
ERRCODEУÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÐºÐ¾Ð´ оÑибки (
SQLSTATE). Ðод оÑибки задаÑÑÑÑ Ð»Ð¸Ð±Ð¾ по имени, как показано в ÐÑиложении A, или напÑÑмÑÑ, пÑÑиÑимволÑнÑй кодSQLSTATE.COLUMNCONSTRAINTDATATYPETABLESCHEMAÐÑедоÑÑавлÑÐµÑ Ð¸Ð¼Ñ ÑооÑвеÑÑÑвÑÑÑего обÑекÑа, ÑвÑзанного Ñ Ð¾Ñибкой.
ÐÑÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ Ð¿ÑеÑÑÐ²Ð°ÐµÑ ÑÑанзакÑÐ¸Ñ Ð¸ ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ ÑообÑение об оÑибке Ñ Ð¿Ð¾Ð´Ñказкой:
RAISE EXCEPTION 'ÐеÑÑÑеÑÑвÑÑÑий ID --> %', user_id
USING HINT = 'ÐÑовеÑÑÑе Ð²Ð°Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкий ID';СледÑÑÑие два пÑимеÑа демонÑÑÑиÑÑÑÑ ÑквиваленÑнÑе ÑпоÑÐ¾Ð±Ñ Ð·Ð°Ð´Ð°Ð½Ð¸Ñ SQLSTATE:
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
У ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ RAISE еÑÑÑ Ð¸ дÑÑгой ÑинÑакÑиÑ, в коÑоÑом в каÑеÑÑве главного аÑгÑменÑа иÑполÑзÑеÑÑÑ Ð¸Ð¼Ñ Ð¸Ð»Ð¸ код SQLSTATE оÑибки. ÐапÑимеÑ:
RAISE division_by_zero; RAISE SQLSTATE '22012';
ÐÑедложение USING в ÑÑом ÑинÑакÑиÑе можно иÑполÑзоваÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑеопÑеделиÑÑ ÑÑандаÑÑное ÑообÑение об оÑибке, деÑалÑное ÑообÑение, подÑказкÑ. ÐÑÑ Ð¾Ð´Ð¸Ð½ ваÑÐ¸Ð°Ð½Ñ Ð¿ÑедÑдÑÑего пÑимеÑа:
RAISE unique_violation USING MESSAGE = 'ID полÑзоваÑÐµÐ»Ñ Ñже ÑÑÑеÑÑвÑеÑ: ' || user_id;
ÐÑÑ Ð¾Ð´Ð¸Ð½ ваÑÐ¸Ð°Ð½Ñ â иÑполÑзоваÑÑ RAISE USING или RAISE , а вÑÑ Ð¾ÑÑалÑное запиÑаÑÑ Ð² ÑпиÑке ÑÑÐ¾Ð²ÐµÐ½Ñ USINGUSING.
РзаклÑÑиÑелÑнÑй ваÑианÑ, в коÑоÑом RAISE не Ð¸Ð¼ÐµÐµÑ Ð¿Ð°ÑамеÑÑов вообÑе. ÐÑа ÑоÑма Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ ÑолÑко в ÑекÑии EXCEPTION блока и пÑедназнаÑена Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð²ÑоÑно вÑзваÑÑ Ð¾ÑибкÑ, коÑоÑÐ°Ñ ÑейÑÐ°Ñ Ð¿ÐµÑеÑ
ваÑена и обÑабаÑÑваеÑÑÑ.
ÐÑимеÑание
Ðо веÑÑии PostgreSQL 9.1 команда RAISE без паÑамеÑÑов вÑегда вÑзÑвала оÑÐ¸Ð±ÐºÑ Ñ Ð²ÑÑ
одом из блока, ÑодеÑжаÑего акÑивнÑÑ ÑекÑÐ¸Ñ EXCEPTION. ÐÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð½ÐµÐ»ÑÐ·Ñ Ð±Ñло пеÑеÑ
ваÑиÑÑ, даже еÑли RAISE в ÑекÑии EXCEPTION помеÑÑиÑÑ Ð²Ð¾ вложеннÑй блок Ñо Ñвоей ÑекÑией EXCEPTION. ÐÑо бÑло ÑоÑÑено ÑдивиÑелÑнÑм и не ÑовмеÑÑимÑм Ñ Oracle PL/SQL.
ÐÑли в команде RAISE EXCEPTION не задано ни Ð¸Ð¼Ñ ÑÑловиÑ, ни код SQLSTATE, по ÑмолÑÐ°Ð½Ð¸Ñ Ð²ÑдаÑÑÑÑ Ð¸ÑклÑÑение ERRCODE_RAISE_EXCEPTION (P0001). ÐÑли не задан ÑекÑÑ ÑообÑениÑ, по ÑмолÑÐ°Ð½Ð¸Ñ Ð² каÑеÑÑве ÑÑого ÑекÑÑа пеÑедаÑÑÑÑ Ð¸Ð¼Ñ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸Ð»Ð¸ код SQLSTATE.
ÐÑимеÑание
ÐÑи задании SQLSTATE кода необÑзаÑелÑно иÑполÑзоваÑÑ ÑолÑко ÑпиÑок пÑедопÑеделÑннÑÑ
кодов оÑибок. РкаÑеÑÑве кода оÑибки Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»Ñбое пÑÑиÑимволÑное знаÑение, ÑоÑÑоÑÑее из ÑиÑÑ Ð¸/или ASCII Ñимволов в веÑÑ
нем ÑегиÑÑÑе, кÑоме 00000. Ðе ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ ÐºÐ¾Ð´Ñ Ð¾Ñибок, коÑоÑÑе заканÑиваÑÑÑÑ Ð½Ð° 000, поÑÐ¾Ð¼Ñ ÑÑо Ñак обознаÑаÑÑÑÑ ÐºÐ¾Ð´Ñ ÐºÐ°ÑегоÑий. Ð ÑÑÐ¾Ð±Ñ Ð¸Ñ
пеÑеÑ
ваÑиÑÑ, нÑжно пеÑеÑ
ваÑÑваÑÑ ÑелÑÑ ÐºÐ°ÑегоÑиÑ.
40.8.2. ÐÑовеÑка ÑÑвеÑждений
ÐпеÑаÑÐ¾Ñ ASSERT пÑедÑÑавлÑÐµÑ Ñдобное ÑÑедÑÑво вÑÑавлÑÑÑ Ð¾ÑладоÑнÑе пÑовеÑки в ÑÑнкÑии PL/pgSQL.
ASSERTÑÑловие[ ,ÑообÑение];
ÐдеÑÑ ÑÑловие â ÑÑо логиÑеÑкое вÑÑажение, коÑоÑое, как ожидаеÑÑÑ, должно бÑÑÑ Ð²Ñегда иÑÑиннÑм; еÑли ÑÑо Ñак, опеÑаÑÐ¾Ñ ASSERT болÑÑе ниÑего не делаеÑ. ÐÑли же оно возвÑаÑÐ°ÐµÑ Ð»Ð¾Ð¶Ñ Ð¸Ð»Ð¸ NULL, ÑÑÐ¾Ñ Ð¾Ð¿ÐµÑаÑÐ¾Ñ Ð²ÑдаÑÑ Ð¸ÑклÑÑение ASSERT_FAILURE. (ÐÑли оÑибка пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð¿Ñи вÑÑиÑлении ÑÑловиÑ, она вÑдаÑÑÑÑ ÐºÐ°Ðº обÑÑÐ½Ð°Ñ Ð¾Ñибка.)
ÐÑли в нÑм задаÑÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑное ÑообÑение, ÑезÑлÑÑÐ°Ñ ÑÑого вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (еÑли он не NULL) заменÑÐµÑ ÑообÑение об оÑибке по ÑмолÑÐ°Ð½Ð¸Ñ Â«assertion failed» (наÑÑÑение иÑÑинноÑÑи), в ÑлÑÑае, еÑли ÑÑловие не вÑполнÑеÑÑÑ. РобÑÑном ÑлÑÑае, когда ÑÑловие ÑÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð²ÑполнÑеÑÑÑ, вÑÑажение ÑообÑÐµÐ½Ð¸Ñ Ð½Ðµ вÑÑиÑлÑеÑÑÑ.
ÐÑовеÑÐºÑ ÑÑвеÑждений можно вклÑÑиÑÑ Ð¸Ð»Ð¸ оÑклÑÑиÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð½ÑигÑÑаÑионного паÑамеÑÑа plpgsql.check_asserts, пÑинимаÑÑего логиÑеÑкое знаÑение; по ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð½Ð° вклÑÑена (on). ÐÑли ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¾ÑклÑÑÑн (off), опеÑаÑоÑÑ ASSERT ниÑего не делаÑÑ.
УÑÑиÑе, ÑÑо опеÑаÑÐ¾Ñ ASSERT пÑедназнаÑен Ð´Ð»Ñ Ð²ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑогÑаммнÑÑ
деÑекÑов, а не Ð´Ð»Ñ Ð²Ñвода обÑÑнÑÑ
оÑибок (Ð´Ð»Ñ ÑÑого иÑполÑзÑеÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¾Ñ RAISE, опиÑаннÑй вÑÑе).