40.3. ÐбÑÑвлениÑ
ÐÑе пеÑеменнÑе, иÑполÑзÑемÑе в блоке, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð² ÑекÑии обÑÑвлениÑ. (Ðа иÑклÑÑением пеÑеменной-ÑÑÑÑÑика Ñикла FOR, коÑоÑÐ°Ñ Ð¾Ð±ÑÑвлÑеÑÑÑ Ð°Ð²ÑомаÑиÑеÑки. ÐÐ»Ñ Ñикла по Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ñ ÑиÑел авÑомаÑиÑеÑки обÑÑвлÑеÑÑÑ ÑелоÑиÑÐ»ÐµÐ½Ð½Ð°Ñ Ð¿ÐµÑеменнаÑ, а Ð´Ð»Ñ Ñикла по ÑезÑлÑÑаÑам кÑÑÑоÑа - пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñипа record.)
ÐеÑеменнÑе PL/pgSQL могÑÑ Ð¸Ð¼ÐµÑÑ Ð»Ñбой Ñип даннÑÑ
SQL, Ñакой как integer, varchar, char.
ÐÑимеÑÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменнÑÑ :
user_id integer; quantity numeric(5); url varchar; myrow tablename%ROWTYPE; myfield tablename.columnname%TYPE; arow RECORD;
ÐбÑий ÑинÑакÑÐ¸Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменной:
имÑ[ CONSTANT ]Ñип[ COLLATEимÑ_пÑавила_ÑоÑÑиÑовки] [ NOT NULL ] [ { DEFAULT | := | = }вÑÑажение];
ÐÑедложение DEFAULT, еÑли пÑиÑÑÑÑÑвÑеÑ, задаÑÑ Ð½Ð°ÑалÑное знаÑение, коÑоÑое пÑиÑваиваеÑÑÑ Ð¿ÐµÑеменной пÑи вÑ
оде в блок. ÐÑли оÑÑÑÑÑÑвÑеÑ, Ñо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¸Ð½Ð¸ÑиализиÑÑеÑÑÑ SQL-знаÑением NULL. Указание CONSTANT пÑедоÑвÑаÑÐ°ÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ знаÑÐµÐ½Ð¸Ñ Ð¿ÐµÑеменной поÑле иниÑиализаÑии, Ñаким обÑазом, знаÑение оÑÑаÑÑÑÑ Ð¿Ð¾ÑÑоÑннÑм в ÑеÑение вÑего блока. ÐаÑамеÑÑ COLLATE опÑеделÑÐµÑ Ð¿Ñавило ÑоÑÑиÑовки, коÑоÑое бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð´Ð»Ñ ÑÑой пеÑеменной (Ñм. ÐодÑаздел 40.3.6). ÐÑли Ñказано NOT NULL, Ñо попÑÑка пÑиÑвоиÑÑ NULL во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÑиведÑÑ Ðº оÑибке. ÐÑе пеÑеменнÑе, обÑÑвленнÑе как NOT NULL, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð¼ÐµÑÑ Ð½ÐµÐ¿ÑÑÑÑе знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ. Ðожно иÑполÑзоваÑÑ Ð·Ð½Ð°Ðº ÑавенÑÑва (=) вмеÑÑо ÑовмеÑÑимого Ñ PL/SQL :=.
ÐнаÑение по ÑмолÑÐ°Ð½Ð¸Ñ Ð²ÑÑиÑлÑеÑÑÑ Ð¸ пÑиÑваиваеÑÑÑ Ð¿ÐµÑеменной каждÑй Ñаз пÑи вÑ
оде в блок (не ÑолÑко пÑи пеÑвом вÑзове ÑÑнкÑии). Так, напÑимеÑ, еÑли пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñипа timestamp Ð¸Ð¼ÐµÐµÑ ÑÑнкÑÐ¸Ñ now() в каÑеÑÑве знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ, ÑÑо пÑиведÑÑ Ðº ÑомÑ, ÑÑо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð²Ñегда бÑÐ´ÐµÑ ÑодеÑжаÑÑ Ð²ÑÐµÐ¼Ñ ÑекÑÑего вÑзова ÑÑнкÑии, а не вÑемÑ, когда ÑÑнкÑÐ¸Ñ Ð±Ñла пÑедваÑиÑелÑно ÑкомпилиÑована.
ÐÑимеÑÑ:
quantity integer DEFAULT 32; url varchar := 'http://mysite.com'; user_id CONSTANT integer := 10;
40.3.1. ÐбÑÑвление паÑамеÑÑов ÑÑнкÑии
ÐеÑеданнÑе в ÑÑнкÑÐ¸Ñ Ð¿Ð°ÑамеÑÑÑ Ð¸Ð¼ÐµÐ½ÑÑÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑами $1, $2 и Ñ. д. ÐополниÑелÑно, Ð´Ð»Ñ ÑлÑÑÑÐµÐ½Ð¸Ñ ÑиÑаемоÑÑи, можно обÑÑвиÑÑ Ð¿ÑÐµÐ²Ð´Ð¾Ð½Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑов $. Ðибо пÑевдоним, либо ÑиÑÑовой иденÑиÑикаÑÐ¾Ñ Ð¸ÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð¾Ð±Ð¾Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑа.n
СоздаÑÑ Ð¿Ñевдоним можно двÑÐ¼Ñ ÑпоÑобами. ÐÑедпоÑÑиÑелÑнÑй ÑпоÑоб ÑÑо даÑÑ Ð¸Ð¼Ñ Ð¿Ð°ÑамеÑÑÑ Ð² команде CREATE FUNCTION, напÑимеÑ:
CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;ÐÑÑгой ÑпоÑоб ÑÑо Ñвное обÑÑвление пÑевдонима пÑи помоÑи ÑинÑакÑиÑа:
имÑALIAS FOR $n;
ÐÑедÑдÑÑий пÑÐ¸Ð¼ÐµÑ Ð´Ð»Ñ ÑÑого ÑÑÐ¸Ð»Ñ Ð²ÑглÑÐ´Ð¸Ñ Ñак:
CREATE FUNCTION sales_tax(real) RETURNS real AS $$
DECLARE
subtotal ALIAS FOR $1;
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;ÐÑимеÑание
ÐÑи два пÑимеÑа не полноÑÑÑÑ ÑквиваленÑнÑ. РпеÑвом ÑлÑÑае на subtotal можно ÑÑÑлаÑÑÑÑ ÐºÐ°Ðº sales_tax.subtotal, а во вÑоÑом ÑлÑÑае ÑÐ°ÐºÐ°Ñ ÑÑÑлка невозможна. (ÐÑли Ð±Ñ Ðº внÑÑÑÐµÐ½Ð½ÐµÐ¼Ñ Ð±Ð»Ð¾ÐºÑ Ð±Ñла добавлена меÑка, Ñо subtotal можно бÑло Ð±Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑÑ ÑÑой меÑкой.)
ÐÑÑ Ð½ÐµÑколÑко пÑимеÑов:
CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
DECLARE
v_string ALIAS FOR $1;
index ALIAS FOR $2;
BEGIN
-- вÑÑиÑлениÑ, иÑполÑзÑÑÑие v_string и index
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURNS text AS $$
BEGIN
RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;
$$ LANGUAGE plpgsql;Ðогда ÑÑнкÑÐ¸Ñ Ð½Ð° PL/pgSQL обÑÑвлÑеÑÑÑ Ñ Ð²ÑÑ
однÑми паÑамеÑÑами, им вÑдаÑÑÑÑ ÑиÑÑовÑе иденÑиÑикаÑоÑÑ $ и Ð´Ð»Ñ Ð½Ð¸Ñ
можно ÑоздаваÑÑ Ð¿ÑÐµÐ²Ð´Ð¾Ð½Ð¸Ð¼Ñ ÑоÑно Ñаким же ÑпоÑобом, как и Ð´Ð»Ñ Ð¾Ð±ÑÑнÑÑ
вÑ
однÑÑ
паÑамеÑÑов. ÐÑÑ
одной паÑамеÑÑ ÑÑо ÑакÑиÑеÑки пеÑеменнаÑ, ÑÑаÑÑÑÑÑÐ°Ñ Ñ NULL и коÑоÑой пÑиÑваиваеÑÑÑ Ð·Ð½Ð°Ñение во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÑнкÑии. ÐозвÑаÑаеÑÑÑ Ð¿Ð¾Ñледнее пÑиÑвоенное знаÑение. ÐапÑимеÑ, ÑÑнкÑÐ¸Ñ sales_tax Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÐµÑепиÑана Ñак: n
CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
BEGIN
tax := subtotal * 0.06;
END;
$$ LANGUAGE plpgsql; ÐбÑаÑиÑе внимание, ÑÑо Ð¼Ñ Ð¾Ð¿ÑÑÑили RETURNS real â Ñ
оÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло и вклÑÑиÑÑ, но ÑÑо бÑло Ð±Ñ Ð¸Ð·Ð»Ð¸Ñним.
ÐÑÑ Ð¾Ð´Ð½Ñе паÑамеÑÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð´Ð»Ñ Ð²Ð¾Ð·Ð²ÑаÑÐµÐ½Ð¸Ñ Ð½ÐµÑколÑÐºÐ¸Ñ Ð·Ð½Ð°Ñений. ÐÑоÑÑейÑий пÑимеÑ:
CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
BEGIN
sum := x + y;
prod := x * y;
END;
$$ LANGUAGE plpgsql; Ðак обÑÑждалоÑÑ Ð² ÐодÑазделе 35.4.4, здеÑÑ ÑакÑиÑеÑки ÑоздаÑÑÑÑ Ð°Ð½Ð¾Ð½Ð¸Ð¼Ð½Ñй Ñип record Ð´Ð»Ñ Ð²Ð¾Ð·Ð²ÑаÑÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑа ÑÑнкÑии. ÐÑли иÑполÑзÑеÑÑÑ Ð¿Ñедложение RETURNS, Ñо оно должно вÑглÑдеÑÑ ÐºÐ°Ðº RETURNS record.
ÐÑÑÑ ÐµÑÑ ÑпоÑоб обÑÑвиÑÑ ÑÑнкÑÐ¸Ñ Ð½Ð° PL/pgSQL Ñ Ð¸ÑполÑзованием RETURNS TABLE, напÑимеÑ:
CREATE FUNCTION extended_sales(p_itemno int)
RETURNS TABLE(quantity int, total numeric) AS $$
BEGIN
RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales s
WHERE s.itemno = p_itemno;
END;
$$ LANGUAGE plpgsql; ÐÑо в ÑоÑноÑÑи ÑооÑвеÑÑÑвÑÐµÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ или неÑколÑкиÑ
паÑамеÑÑов OUT и ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ RETURNS SETOF .некий_Ñип
ÐÐ»Ñ ÑÑнкÑии на PL/pgSQL, возвÑаÑаÑÑей полимоÑÑнÑй Ñип (anyelement, anyarray, anynonarray, anyenum, anyrange), ÑоздаÑÑÑÑ ÑпеÑиалÑнÑй паÑамеÑÑ $0. Ðго Ñип даннÑÑ
ÑооÑвеÑÑÑвÑÐµÑ ÑипÑ, ÑакÑиÑеÑки возвÑаÑÐ°ÐµÐ¼Ð¾Ð¼Ñ ÑÑнкÑией, и коÑоÑÑй ÑÑÑанавливаеÑÑÑ Ð½Ð° оÑновании ÑакÑиÑеÑкиÑ
Ñипов вÑ
однÑÑ
паÑамеÑÑов (Ñм. ÐодÑаздел 35.2.5). ÐÑо позволÑÐµÑ ÑÑнкÑии обÑаÑаÑÑÑÑ Ðº ÑакÑиÑеÑки возвÑаÑÐ°ÐµÐ¼Ð¾Ð¼Ñ ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
, как показано в ÐодÑазделе 40.3.3. ÐаÑамеÑÑ $0 иниÑиализиÑÑеÑÑÑ Ð² NULL и его можно изменÑÑÑ Ð²Ð½ÑÑÑи ÑÑнкÑии. Таким обÑазом, его можно иÑполÑзоваÑÑ Ð´Ð»Ñ Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑаемого знаÑениÑ, Ñ
оÑÑ ÑÑо необÑзаÑелÑно. ÐаÑамеÑÑÑ $0 можно даÑÑ Ð¿Ñевдоним. Ð ÑледÑÑÑем пÑимеÑе ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ñ Ð»ÑбÑм Ñипом даннÑÑ
, поддеÑживаÑÑим опеÑаÑÐ¾Ñ +:
CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
result ALIAS FOR $0;
BEGIN
result := v1 + v2 + v3;
RETURN result;
END;
$$ LANGUAGE plpgsql;Такой же ÑÑÑÐµÐºÑ Ð¿Ð¾Ð»ÑÑаеÑÑÑ Ð¿Ñи обÑÑвлении одного или неÑколÑкиÑ
вÑÑ
однÑÑ
паÑамеÑÑов полимоÑÑного Ñипа. ÐÑи ÑÑом $0 не ÑоздаÑÑÑÑ; вÑÑ
однÑе паÑамеÑÑÑ Ñами иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ ÑÑой Ñели. ÐапÑимеÑ:
CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,
OUT sum anyelement)
AS $$
BEGIN
sum := v1 + v2 + v3;
END;
$$ LANGUAGE plpgsql;40.3.2. ALIAS
новое_имÑALIAS FORÑÑаÑое_имÑ;
СинÑакÑÐ¸Ñ ALIAS более обÑий, Ñем пÑедполагалоÑÑ Ð² пÑедÑдÑÑем Ñазделе: пÑÐµÐ²Ð´Ð¾Ð½Ð¸Ð¼Ñ Ð¼Ð¾Ð¶Ð½Ð¾ обÑÑвлÑÑÑ Ð´Ð»Ñ Ð»ÑбÑÑ
пеÑеменнÑÑ
, а не ÑолÑко Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑов ÑÑнкÑии. ÐÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð¿ÑакÑиÑеÑÐºÐ°Ñ Ð¿Ð¾Ð»Ñза в Ñом, ÑÑÐ¾Ð±Ñ Ð½Ð°Ð·Ð½Ð°ÑиÑÑ Ð´ÑÑгие имена пеÑеменнÑм Ñ Ð¿ÑедопÑеделÑннÑми названиÑми, Ñаким как NEW или OLD в ÑÑиггеÑной пÑоÑедÑÑе.
ÐÑимеÑÑ:
DECLARE prior ALIAS FOR old; updated ALIAS FOR new;
ÐоÑколÑÐºÑ ALIAS даÑÑ Ð´Ð²Ð° ÑазлиÑнÑÑ
ÑпоÑоба Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð´Ð½Ð¸Ñ
и ÑеÑ
же обÑекÑов, Ñо его неогÑаниÑенное иÑполÑзование Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к пÑÑаниÑе. ÐÑÑÑе вÑего иÑполÑзоваÑÑ ALIAS Ð´Ð»Ñ Ð¿ÐµÑÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑедопÑеделÑннÑÑ
имÑн.
40.3.3. ÐаÑледование Ñипов даннÑÑ
пеÑеменнаÑ%TYPEÐонÑÑÑÑкÑÐ¸Ñ %TYPE пÑедоÑÑавлÑÐµÑ Ñип даннÑÑ
пеÑеменной или ÑÑолбÑа ÑаблиÑÑ. ÐÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð´Ð»Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменнÑÑ
, ÑодеÑжаÑиÑ
знаÑÐµÐ½Ð¸Ñ Ð¸Ð· Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
. ÐапÑимеÑ, Ð´Ð»Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменной Ñ Ñаким же Ñипом, как и ÑÑÐ¾Ð»Ð±ÐµÑ user_id в ÑаблиÑе users нÑжно напиÑаÑÑ:
user_id users.user_id%TYPE;
ÐÑполÑзÑÑ %TYPE, не нÑжно знаÑÑ Ñип даннÑÑ
ÑÑÑÑкÑÑÑÑ, на коÑоÑÑÑ Ð²Ñ ÑÑÑлаеÑеÑÑ. Ð Ñамое главное, еÑли в бÑдÑÑем Ñип даннÑÑ
измениÑÑÑ (напÑимеÑ: Ñип даннÑÑ
Ð´Ð»Ñ user_id поменÑеÑÑÑ Ñ integer на real), Ñо вам Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ понадобиÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑÑ Ð¾Ð¿Ñеделение ÑÑнкÑии.
ÐÑполÑзование %TYPE оÑобенно полезно в полимоÑÑнÑÑ
ÑÑнкÑиÑÑ
, поÑколÑÐºÑ ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
, необÑ
одимÑе Ð´Ð»Ñ Ð²Ð½ÑÑÑенниÑ
пеÑеменнÑÑ
, могÑÑ Ð¼ÐµÐ½ÑÑÑÑÑ Ð¾Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ вÑзова к дÑÑгомÑ. СооÑвеÑÑÑвÑÑÑие пеÑеменнÑе могÑÑ Ð±ÑÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ñ Ð¿Ñименением %TYPE к аÑгÑменÑам и возвÑаÑÐ°ÐµÐ¼Ð¾Ð¼Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑÑнкÑии.
40.3.4. Ð¢Ð¸Ð¿Ñ ÐºÐ¾ÑÑежей
имÑимÑ_ÑаблиÑÑ%ROWTYPE;имÑимÑ_ÑоÑÑавного_Ñипа;
ÐеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑоÑÑавного Ñипа назÑваеÑÑÑ Ð¿ÐµÑеменной-коÑÑежем (или пеÑеменной Ñипа коÑÑежа). ÐнаÑением Ñакой пеÑеменной Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑелÑй коÑÑеж, полÑÑеннÑй в ÑезÑлÑÑаÑе вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа SELECT или FOR, пÑи ÑÑловии, ÑÑо Ð½Ð°Ð±Ð¾Ñ ÑÑолбÑов запÑоÑа ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°ÑÐ²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ ÑÐ¸Ð¿Ñ Ð¿ÐµÑеменной. ÐоÑÑÑп к оÑделÑнÑм полÑм знаÑÐµÐ½Ð¸Ñ ÐºÐ¾ÑÑежа оÑÑÑеÑÑвлÑеÑÑÑ ÐºÐ°Ðº обÑÑно, ÑеÑез ÑоÑкÑ, напÑÐ¸Ð¼ÐµÑ rowvar.field.
ÐеÑеменнаÑ-коÑÑеж Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð±ÑÑвлена Ñ Ñаким же Ñипом, как и ÑÑÑока в ÑÑÑеÑÑвÑÑÑей ÑаблиÑе или пÑедÑÑавлении, иÑполÑзÑÑ Ð½Ð¾ÑаÑÐ¸Ñ Ð¸Ð¼Ñ_ÑаблиÑÑ%ROWTYPE; или Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑоÑÑавного Ñипа. (ÐоÑколÑÐºÑ ÐºÐ°Ð¶Ð´Ð°Ñ ÑаблиÑа Ð¸Ð¼ÐµÐµÑ ÑооÑвеÑÑÑвÑÑÑий ÑоÑÑавной Ñип Ñ Ñаким же именем, Ñо на Ñамом деле в Postgres Pro не Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениÑ, пиÑеÑе ли Ð²Ñ %ROWTYPE или неÑ. Ðо иÑполÑзование %ROWTYPE более пеÑеноÑимо.)
ÐаÑамеÑÑÑ ÑÑнкÑии могÑÑ Ð±ÑÑÑ ÑоÑÑавного Ñипа (ÑÑÑоки ÑаблиÑÑ). Ð ÑÑом ÑлÑÑае ÑооÑвеÑÑÑвÑÑÑий иденÑиÑикаÑÐ¾Ñ $ бÑÐ´ÐµÑ Ð¿ÐµÑеменной-коÑÑежем, Ð¿Ð¾Ð»Ñ ÐºÐ¾ÑоÑой можно вÑбиÑаÑÑ, напÑÐ¸Ð¼ÐµÑ n$1.user_id.
ТолÑко опÑеделÑннÑе полÑзоваÑелем ÑÑолбÑÑ ÑаблиÑÑ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ Ð² пеÑеменной Ñипа коÑÑежа, но не OID или дÑÑгие ÑиÑÑемнÑе ÑÑолбÑÑ (поÑÐ¾Ð¼Ñ ÑÑо ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑока пÑедÑÑавлениÑ). ÐÐ¾Ð»Ñ Ð² Ñаком Ñипе наÑледÑÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ð¸ ÑоÑноÑÑÑ Ð¾Ñ Ñипов даннÑÑ
ÑÑолбÑов ÑаблиÑÑ, ÑакиÑ
как char(.n)
Ðиже пÑиведÑн пÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑоÑÑавнÑÑ
Ñипов. table1 и table2 ÑÑо ÑÑÑеÑÑвÑÑÑие ÑаблиÑÑ, имеÑÑие, по менÑÑей меÑе, пеÑеÑиÑленнÑе ÑÑолбÑÑ:
CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$
DECLARE
t2_row table2%ROWTYPE;
BEGIN
SELECT * INTO t2_row FROM table2 WHERE ... ;
RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
END;
$$ LANGUAGE plpgsql;
SELECT merge_fields(t.*) FROM table1 t WHERE ... ;40.3.5. Тип record
Ð¸Ð¼Ñ RECORD;ÐеÑеменнÑе Ñипа record поÑ
ожи на пеÑеменнÑе-коÑÑежи, но они не имеÑÑ Ð¿ÑедопÑеделÑнной ÑÑÑÑкÑÑÑÑ. Ðни пÑиобÑеÑаÑÑ ÑакÑиÑеÑкÑÑ ÑÑÑÑкÑÑÑÑ Ð¾Ñ ÑÑÑоки, коÑоÑÐ°Ñ Ð¸Ð¼ пÑиÑваиваеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ð¼Ð¸ SELECT или FOR. СÑÑÑкÑÑÑа пеÑеменной Ñипа record Ð¼Ð¾Ð¶ÐµÑ Ð¼ÐµÐ½ÑÑÑÑÑ ÐºÐ°Ð¶Ð´Ñй Ñаз пÑи пÑиÑваивании знаÑениÑ. СледÑÑвием ÑÑого ÑвлÑеÑÑÑ Ñо, ÑÑо пока знаÑение не пÑиÑвоено пеÑвÑй Ñаз, пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñипа record не Ð¸Ð¼ÐµÐµÑ ÑÑÑÑкÑÑÑÑ Ð¸ лÑÐ±Ð°Ñ Ð¿Ð¾Ð¿ÑÑка полÑÑиÑÑ Ð´Ð¾ÑÑÑп к оÑделÑÐ½Ð¾Ð¼Ñ Ð¿Ð¾Ð»Ñ Ð¿ÑиведÑÑ Ðº оÑибке во вÑÐµÐ¼Ñ Ð²ÑполнениÑ.
ÐбÑаÑиÑе внимание, ÑÑо RECORD ÑÑо не подлиннÑй Ñип даннÑÑ
, а ÑолÑко лиÑÑ Ð·Ð°Ð¿Ð¾Ð»Ð½Ð¸ÑелÑ. Также ÑледÑÐµÑ Ð¿Ð¾Ð½Ð¸Ð¼Ð°ÑÑ, ÑÑо ÑÑнкÑÐ¸Ñ Ð½Ð° PL/pgSQL, имеÑÑÐ°Ñ Ñип возвÑаÑаемого знаÑÐµÐ½Ð¸Ñ record, ÑÑо не Ñо же Ñамое, ÑÑо и пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñипа record, Ñ
оÑÑ ÑÐ°ÐºÐ°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑ Ð¿ÐµÑеменнÑÑ Ñипа record Ð´Ð»Ñ Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ñвоего ÑезÑлÑÑаÑа. РобоиÑ
ÑлÑÑаÑÑ
ÑакÑиÑеÑÐºÐ°Ñ ÑÑÑÑкÑÑÑа ÑÑÑоки неизвеÑÑна во вÑÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÑнкÑии, но Ð´Ð»Ñ ÑÑнкÑии, возвÑаÑаÑÑей record, ÑакÑиÑеÑÐºÐ°Ñ ÑÑÑÑкÑÑÑа опÑеделÑеÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ ÑазбоÑа вÑзÑваÑÑего запÑоÑа, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñипа record Ð¼Ð¾Ð¶ÐµÑ Ð¼ÐµÐ½ÑÑÑ ÑÐ²Ð¾Ñ ÑÑÑÑкÑÑÑÑ Ð½Ð° леÑÑ.
40.3.6. УпоÑÑдоÑение пеÑеменнÑÑ PL/pgSQL
Ðогда ÑÑнкÑÐ¸Ñ Ð½Ð° PL/pgSQL Ð¸Ð¼ÐµÐµÑ Ð¾Ð´Ð¸Ð½ или неÑколÑко паÑамеÑÑов ÑоÑÑиÑÑемÑÑ Ñипов даннÑÑ , пÑавило ÑоÑÑиÑовки опÑеделÑеÑÑÑ Ð¿Ñи каждом вÑзове ÑÑнкÑии в завиÑимоÑÑи Ð¾Ñ Ð¿Ñавил ÑоÑÑиÑовки ÑакÑиÑеÑÐºÐ¸Ñ Ð°ÑгÑменÑов, как опиÑано в Разделе 22.2. ÐÑли оно опÑеделено ÑÑпеÑно (Ñ. е. ÑÑеди аÑгÑменÑов Ð½ÐµÑ ÐºÐ¾Ð½ÑликÑов Ð¼ÐµÐ¶Ð´Ñ Ð½ÐµÑвнÑми пÑавилами ÑоÑÑиÑовки), Ñо вÑе ÑооÑвеÑÑÑвÑÑÑие паÑамеÑÑÑ Ð½ÐµÑвно ÑÑакÑÑÑÑÑÑ ÐºÐ°Ðº имеÑÑее ÑÑо пÑавило ÑоÑÑиÑовки. ÐнÑÑÑи ÑÑнкÑии ÑÑо бÑÐ´ÐµÑ Ð²Ð»Ð¸ÑÑÑ Ð½Ð° поведение опеÑаÑоÑов, завиÑÑÑÐ¸Ñ Ð¾Ñ Ð¸ÑполÑзÑемого пÑавила ÑоÑÑиÑовки. РаÑÑмоÑÑим пÑимеÑ:
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
RETURN a < b;
END;
$$ LANGUAGE plpgsql;
SELECT less_than(text_field_1, text_field_2) FROM table1;
SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; РпеÑвом ÑлÑÑае less_than бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑ Ð´Ð»Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñее пÑавило ÑоÑÑиÑовки Ð´Ð»Ñ text_field_1 и text_field_2, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº во вÑоÑом ÑлÑÑае бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð¿Ñавило C.
ÐÑоме Ñого, опÑеделÑнное Ð´Ð»Ñ Ð²Ñзова ÑÑнкÑии пÑавило ÑоÑÑиÑовки Ñакже бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð´Ð»Ñ Ð»ÑбÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑÑ Ð¿ÐµÑеменнÑÑ ÑооÑвеÑÑÑвÑÑÑего Ñипа. Таким обÑазом, ÑÑнкÑÐ¸Ñ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ ÑабоÑаÑÑ Ð¿Ð¾-дÑÑгомÑ, еÑли ÐµÑ Ð¿ÐµÑепиÑаÑÑ Ñак:
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
$$ LANGUAGE plpgsql;ÐÑли паÑамеÑÑов Ñ Ñипами даннÑÑ , поддеÑживаÑÑими ÑоÑÑиÑовкÑ, неÑ, или Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑов невозможно опÑеделиÑÑ Ð¾Ð±Ñее пÑавило ÑоÑÑиÑовки, Ñогда Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑов и локалÑнÑÑ Ð¿ÐµÑеменнÑÑ Ð¿ÑименÑÑÑÑÑ Ð¿Ñавила, пÑинÑÑÑе Ð´Ð»Ñ Ð¸Ñ Ñипа даннÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ (коÑоÑÑе обÑÑно ÑовпадаÑÑ Ñ Ð¿Ñавилами ÑоÑÑиÑовки по ÑмолÑаниÑ, пÑинÑÑÑми Ð´Ð»Ñ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ , но могÑÑ Ð¾ÑлиÑаÑÑÑÑ Ð´Ð»Ñ Ð¿ÐµÑеменнÑÑ Ð´Ð¾Ð¼ÐµÐ½Ð½ÑÑ Ñипов).
ÐокалÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð¿Ñавило ÑоÑÑиÑовки, оÑлиÑное Ð¾Ñ Ð¿Ñавила по ÑмолÑаниÑ. ÐÐ»Ñ ÑÑого иÑполÑзÑеÑÑÑ Ð¿Ð°ÑамеÑÑ COLLATE в обÑÑвлении пеÑеменной, напÑимеÑ:
DECLARE
local_a text COLLATE "en_US";ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¿ÐµÑеопÑеделÑÐµÑ Ð¿Ñавило ÑоÑÑиÑовки, коÑоÑое полÑÑила Ð±Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð² ÑооÑвеÑÑÑвии Ñ Ð²ÑÑеÑказаннÑми пÑавилами.
Ð, конеÑно же, можно Ñвно ÑказÑваÑÑ Ð¿Ð°ÑамеÑÑ COLLATE Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑнÑÑ
опеÑаÑий внÑÑÑи ÑÑнкÑии, еÑли к ним ÑÑебÑеÑÑÑ Ð¿ÑимениÑÑ ÐºÐ¾Ð½ÐºÑеÑное пÑавило ÑоÑÑиÑовки. ÐапÑимеÑ:
CREATE FUNCTION less_than_c(a text, b text) RETURNS boolean AS $$
BEGIN
RETURN a < b COLLATE "C";
END;
$$ LANGUAGE plpgsql;Ðак и в обÑÑной SQL-команде, ÑÑо пеÑеопÑеделÑÐµÑ Ð¿Ñавила ÑоÑÑиÑовки, ÑвÑзаннÑе Ñ Ð¿Ð¾Ð»Ñми ÑаблиÑÑ, паÑамеÑÑами и локалÑнÑми пеÑеменнÑми, коÑоÑÑе иÑполÑзÑÑÑÑÑ Ð² данном вÑÑажении.