PREPARE
PREPARE â подгоÑовиÑÑ Ð¾Ð¿ÐµÑаÑÐ¾Ñ Ðº вÑполнениÑ
СинÑакÑиÑ
PREPAREимÑ[ (Ñип_даннÑÑ[, ...] ) ] ASопеÑаÑоÑ
ÐпиÑание
PREPARE ÑоздаÑÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй опеÑаÑоÑ. ÐодгоÑовленнÑй опеÑаÑÐ¾Ñ Ð¿ÑедÑÑавлÑÐµÑ Ñобой обÑÐµÐºÑ Ð½Ð° ÑÑоÑоне ÑеÑвеÑа, позволÑÑÑий опÑимизиÑоваÑÑ Ð¿ÑоизводиÑелÑноÑÑÑ Ð¿Ñиложений. Ðогда вÑполнÑеÑÑÑ PREPARE, ÑказаннÑй опеÑаÑÐ¾Ñ ÑазбиÑаеÑÑÑ, анализиÑÑеÑÑÑ Ð¸ пеÑепиÑÑваеÑÑÑ. ÐÑи поÑледÑÑÑем вÑполнении ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXECUTE подгоÑовленнÑй опеÑаÑÐ¾Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÑеÑÑÑ Ð¸ иÑполнÑеÑÑÑ. Такое Ñазделение ÑÑÑда иÑклÑÑÐ°ÐµÑ Ð¿Ð¾Ð²ÑоÑнÑй ÑÐ°Ð·Ð±Ð¾Ñ Ð·Ð°Ð¿ÑоÑа, пÑи ÑÑом позволÑÐµÑ Ð²ÑбÑаÑÑ Ð½Ð°Ð¸Ð»ÑÑÑий план вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² завиÑимоÑÑи Ð¾Ñ Ð¾Ð¿ÑеделÑннÑÑ
знаÑений паÑамеÑÑов.
ÐодгоÑовленнÑе опеÑаÑоÑÑ Ð¼Ð¾Ð³ÑÑ Ð¿ÑинимаÑÑ Ð¿Ð°ÑамеÑÑÑ â знаÑениÑ, коÑоÑÑе подÑÑавлÑÑÑÑÑ Ð² опеÑаÑоÑ, когда он ÑобÑÑвенно вÑполнÑеÑÑÑ. ÐÑи Ñоздании подгоÑовленного опеÑаÑоÑа к ÑÑим паÑамеÑÑам можно обÑаÑаÑÑÑÑ Ð¿Ð¾ поÑÑÐ´ÐºÐ¾Ð²Ð¾Ð¼Ñ Ð½Ð¾Ð¼ÐµÑÑ, иÑполÑзÑÑ Ð·Ð°Ð¿Ð¸ÑÑ $1, $2 и Ñ. д. ÐополниÑелÑно можно ÑказаÑÑ ÑпиÑок ÑооÑвеÑÑÑвÑÑÑиÑ
Ñипов даннÑÑ
паÑамеÑÑов. ÐÑли Ñип даннÑÑ
паÑамеÑÑа не Ñказан или обÑÑвлен как unknown (неизвеÑÑнÑй), Ñип вÑводиÑÑÑ Ð¸Ð· конÑекÑÑа, в коÑоÑом ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¸ÑполÑзÑеÑÑÑ Ð²Ð¿ÐµÑвÑе (еÑли ÑÑо возможно). ÐÑи вÑполнении опеÑаÑоÑа ÑакÑиÑеÑкие знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов пеÑедаÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ðµ EXECUTE. Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº EXECUTE.
ÐодгоÑовленнÑе опеÑаÑоÑÑ ÑÑÑеÑÑвÑÑÑ ÑолÑко в ÑÐ°Ð¼ÐºÐ°Ñ ÑекÑÑего ÑеанÑа ÑабоÑÑ Ñ ÐÐ. Ðогда ÑÐµÐ°Ð½Ñ Ð·Ð°Ð²ÐµÑÑаеÑÑÑ, ÑиÑÑема забÑÐ²Ð°ÐµÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй опеÑаÑоÑ, Ñак ÑÑо его надо бÑÐ´ÐµÑ ÑоздаÑÑ Ñнова, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзоваÑÑ Ð´Ð°Ð»ÑÑе. ÐÑо Ñакже ознаÑаеÑ, ÑÑо один подгоÑовленнÑй опеÑаÑÐ¾Ñ Ð½Ðµ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð¾Ð´Ð½Ð¾Ð²Ñеменно неÑколÑкими клиенÑами Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ ; но каждÑй ÐºÐ»Ð¸ÐµÐ½Ñ Ð¼Ð¾Ð¶ÐµÑ ÑоздаÑÑ ÑобÑÑвеннÑй подгоÑовленнÑй опеÑаÑÐ¾Ñ Ð¸ иÑполÑзоваÑÑ ÐµÐ³Ð¾. ÐÑвободиÑÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй опеÑаÑÐ¾Ñ Ð¼Ð¾Ð¶Ð½Ð¾ вÑÑÑнÑÑ, вÑполнив ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ DEALLOCATE.
ÐодгоÑовленнÑе опеÑаÑоÑÑ Ð´Ð°ÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÑÑий вÑигÑÑÑ Ð² пÑоизводиÑелÑноÑÑи, когда в одном ÑеанÑе вÑполнÑеÑÑÑ Ð±Ð¾Ð»ÑÑое ÑиÑло одноÑипнÑÑ Ð¾Ð¿ÐµÑаÑоÑов. ÐÑлиÑие в пÑоизводиÑелÑноÑÑи оÑобенно знаÑиÑелÑно, еÑли опеÑаÑоÑÑ Ð´Ð¾ÑÑаÑоÑно ÑÐ»Ð¾Ð¶Ð½Ñ Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ пеÑезапиÑи, напÑимеÑ, когда в запÑоÑе обÑединÑеÑÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑво ÑÐ°Ð±Ð»Ð¸Ñ Ð¸Ð»Ð¸ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ пÑимениÑÑ Ð½ÐµÑколÑко пÑавил. ÐÑли опеÑаÑÐ¾Ñ Ð¾ÑноÑиÑелÑно пÑоÑÑ Ð² ÑÑом плане, но Ñложен Ð´Ð»Ñ Ð²ÑполнениÑ, вÑигÑÑÑ Ð¾Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑÑ Ð¾Ð¿ÐµÑаÑоÑов бÑÐ´ÐµÑ Ð¼ÐµÐ½ÐµÐµ замеÑнÑм.
ÐаÑамеÑÑÑ
имÑÐÑоизволÑное имÑ, назнаÑаемое Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð¿Ð¾Ð´Ð³Ð¾ÑÐ¾Ð²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ Ð¾Ð¿ÐµÑаÑоÑÑ. Ðно должно бÑÑÑ ÑникалÑнÑм в ÑÐ°Ð¼ÐºÐ°Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ ÑеанÑа; ÑÑо Ð¸Ð¼Ñ Ð·Ð°Ñем иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ оÑÐ²Ð¾Ð±Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ñанее подгоÑовленного опеÑаÑоÑа.
Ñип_даннÑÑТип даннÑÑ Ð¿Ð°ÑамеÑÑа подгоÑовленного опеÑаÑоÑа. ÐÑли Ñип даннÑÑ ÐºÐ¾Ð½ÐºÑеÑного паÑамеÑÑа не задан или задан как
unknown, он бÑÐ´ÐµÑ Ð²ÑводиÑÑÑÑ Ð¸Ð· конÑекÑÑа, в коÑоÑом ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¸ÑполÑзÑеÑÑÑ Ð²Ð¿ÐµÑвÑе. ÐÐ»Ñ Ð¾Ð±ÑаÑÐµÐ½Ð¸Ñ Ðº паÑамеÑÑам в Ñамом подгоÑовленном опеÑаÑоÑе иÑполÑзÑеÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ$1,$2и Ñ. д.опеÑаÑоÑÐÑбой опеÑаÑоÑ
SELECT,INSERT,UPDATE,DELETEилиVALUES.
ÐамеÑаниÑ
ÐÑли подгоÑовленнÑй опеÑаÑÐ¾Ñ Ð²ÑполнÑеÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñаз, ÑеÑÐ²ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð² иÑоге ÑеÑиÑÑ ÑÐ¾Ñ ÑаниÑÑ Ð¸ повÑоÑно иÑполÑзоваÑÑ Ð¾Ð±Ñий план, а не ÑÑÑоиÑÑ Ð¿Ð»Ð°Ð½ каждÑй Ñаз заново. ÐÑо пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿Ñи пеÑвом же вÑполнении, еÑли подгоÑовленнÑй опеÑаÑÐ¾Ñ Ð½Ðµ Ð¸Ð¼ÐµÐµÑ Ð¿Ð°ÑамеÑÑов; в пÑоÑивном ÑлÑÑае ÑолÑко Ñогда, когда обÑий план окажеÑÑÑ Ð½Ðµ знаÑиÑелÑно доÑоже, Ñем план, завиÑÑÑий Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ Ð·Ð½Ð°Ñений. ÐбÑÑно обÑий план вÑбиÑаеÑÑÑ, ÑолÑко еÑли пÑоизводиÑелÑноÑÑÑ Ð·Ð°Ð¿ÑоÑа, пÑедположиÑелÑно, пÑакÑиÑеÑки не завиÑÐ¸Ñ Ð¾Ñ Ð¿ÐµÑедаваемÑÑ Ð·Ð½Ð°Ñений паÑамеÑÑов.
УзнаÑÑ, какой план вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²ÑбиÑÐ°ÐµÑ Postgres Pro Ð´Ð»Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного опеÑаÑоÑа, можно, воÑполÑзовавÑиÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ EXPLAIN. ÐÑли пÑименÑеÑÑÑ Ð¾Ð±Ñий план, он бÑÐ´ÐµÑ ÑодеÑжаÑÑ ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ Ð¿Ð°ÑамеÑÑов $, Ñогда как в наÑÑÑаиваемом плане бÑдÑÑ Ð¿Ð¾Ð´ÑÑÐ°Ð²Ð»ÐµÐ½Ñ ÑакÑиÑеÑкие знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов.n
Ðолее подÑобно о планиÑовании запÑоÑов и ÑÑаÑиÑÑике, коÑоÑÑÑ ÑобиÑÐ°ÐµÑ Postgres Pro Ð´Ð»Ñ ÑÑÐ¸Ñ Ñелей, можно ÑзнаÑÑ Ð² докÑменÑаÑии ANALYZE.
ХоÑÑ Ð¾Ñновной ÑмÑÑл подгоÑовленнÑÑ
опеÑаÑоÑов в Ñом, ÑÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð¼Ð½Ð¾Ð³Ð¾ÐºÑаÑного ÑазбоÑа и планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð¿ÐµÑаÑоÑа, Postgres Pro бÑÐ´ÐµÑ Ð¿ÑинÑдиÑелÑно заново анализиÑоваÑÑ Ð¸ планиÑоваÑÑ Ð²Ñполнение опеÑаÑоÑа вÑÑкий Ñаз, когда обÑекÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
, задейÑÑвованнÑе в опеÑаÑоÑе, подвеÑгаÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñм опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ (DDL) Ñо вÑемени пÑедÑдÑÑего иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного опеÑаÑоÑа. ÐÑоме Ñого, еÑли Ð¾Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð¿ÐµÑаÑоÑа к дÑÑÐ³Ð¾Ð¼Ñ Ð¼ÐµÐ½ÑеÑÑÑ Ð·Ð½Ð°Ñение search_path, опеÑаÑÐ¾Ñ Ð±ÑÐ´ÐµÑ Ñак же ÑазобÑан заново Ñ Ð½Ð¾Ð²Ñм search_path. (ÐоÑледнее поведение поÑвилоÑÑ Ð² PostgreSQL 9.3.) С ÑÑими пÑавилами иÑполÑзование подгоÑовленного опеÑаÑоÑа по ÑÑÑи поÑÑи не оÑлиÑаеÑÑÑ Ð¾Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ и Ñого же запÑоÑа Ñнова и Ñнова, но даÑÑ Ð²ÑигÑÑÑ Ð¿Ð¾ ÑкоÑоÑÑи (еÑли опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑекÑов не менÑÑÑÑÑ), оÑобенно еÑли опÑималÑнÑй план Ð¾Ñ Ñаза к ÑÐ°Ð·Ñ Ð½Ðµ менÑеÑÑÑ. Ðднако ÑазлиÑÐ¸Ñ Ð²ÑÑ Ð¶Ðµ могÑÑ Ð¿ÑоÑвиÑÑÑÑ â напÑимеÑ, когда опеÑаÑÐ¾Ñ Ð¾Ð±ÑаÑаеÑÑÑ Ðº ÑаблиÑе по Ð½ÐµÐ¿Ð¾Ð»Ð½Ð¾Ð¼Ñ Ð¸Ð¼ÐµÐ½Ð¸, а заÑем в ÑÑ
еме, ÑÑоÑÑей в пÑÑи search_path ÑанÑÑе, ÑоздаÑÑÑÑ Ð´ÑÑÐ³Ð°Ñ ÑаблиÑа Ñ Ñаким же именем, авÑомаÑиÑеÑкий пеÑеÑмоÑÑ Ð·Ð°Ð¿ÑоÑа не пÑоиÑÑ
одиÑ, Ñак как никакой обÑÐµÐºÑ Ð² опÑеделении опеÑаÑоÑа не изменилÑÑ. Ðднако, еÑли авÑомаÑиÑеÑкий пеÑеÑмоÑÑ Ð¿ÑоизойдÑÑ Ð² ÑезÑлÑÑаÑе дÑÑгиÑ
изменений, пÑи поÑледÑÑÑем вÑполнении запÑоÑа бÑÐ´ÐµÑ Ð·Ð°Ð´ÐµÐ¹ÑÑвована Ð½Ð¾Ð²Ð°Ñ ÑаблиÑа.
ÐолÑÑиÑÑ ÑпиÑок вÑеÑ
доÑÑÑпнÑÑ
в ÑеанÑе подгоÑовленнÑÑ
опеÑаÑоÑов можно, обÑаÑивÑиÑÑ Ðº ÑиÑÑÐµÐ¼Ð½Ð¾Ð¼Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ pg_prepared_statements.
ÐÑимеÑÑ
Создание подгоÑовленного опеÑаÑоÑа Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ INSERT, коÑоÑÑй заÑем вÑполнÑеÑÑÑ:
PREPARE fooplan (int, text, bool, numeric) AS
INSERT INTO foo VALUES($1, $2, $3, $4);
EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);Создание подгоÑовленного опеÑаÑоÑа Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ SELECT, коÑоÑÑй заÑем вÑполнÑеÑÑÑ:
PREPARE usrrptplan (int) AS
SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid
AND l.date = $2;
EXECUTE usrrptplan(1, current_date); ÐамеÑÑÑе, ÑÑо Ñип даннÑÑ
вÑоÑого паÑамеÑÑа не ÑказÑваеÑÑÑ, Ñак ÑÑо он вÑводиÑÑÑ Ð¸Ð· конÑекÑÑа, в коÑоÑом иÑполÑзÑеÑÑÑ $2.
СовмеÑÑимоÑÑÑ
Ð ÑÑандаÑÑе SQL еÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¾Ñ PREPARE, но он пÑедназнаÑен ÑолÑко Ð´Ð»Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð¾ вÑÑÑаиваемом SQL. ÐÑа веÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑоÑа PREPARE Ð¸Ð¼ÐµÐµÑ Ñакже неÑколÑко дÑÑгой ÑинÑакÑиÑ.