32.7. ÐнÑеÑÑÐµÐ¹Ñ Ð±ÑÑÑÑого пÑÑи
Postgres Pro пÑедоÑÑавлÑÐµÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ Ð´Ð»Ñ Ð¿ÐµÑедаÑи ÑеÑвеÑÑ Ð¿ÑоÑÑÑÑ Ð²Ñзовов ÑÑнкÑий по бÑÑÑÑÐ¾Ð¼Ñ Ð¿ÑÑи.
ÐодÑказка
ÐÑÐ¾Ñ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ Ð½ÐµÑколÑко ÑÑÑаÑел, поÑколÑÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ доÑÑиÑÑ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ð¾Ð¹ пÑоизводиÑелÑноÑÑи и болÑÑей ÑÑнкÑионалÑноÑÑи пÑÑÑм ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного опеÑаÑоÑа, опÑеделÑÑÑего вÑзов ÑÑнкÑии. ÐоÑледÑÑÑее вÑполнение ÑÑого опеÑаÑоÑа Ñ Ð¿ÐµÑедаÑей паÑамеÑÑов и ÑезÑлÑÑаÑов в двоиÑном виде можно ÑÑиÑаÑÑ Ð·Ð°Ð¼ÐµÐ½Ð¾Ð¹ вÑÐ·Ð¾Ð²Ñ Ð¿Ð¾ бÑÑÑÑÐ¾Ð¼Ñ Ð¿ÑÑи.
ФÑнкÑÐ¸Ñ PQfn запÑаÑÐ¸Ð²Ð°ÐµÑ Ð²Ñполнение ÑеÑвеÑной ÑÑнкÑии поÑÑедÑÑвом инÑеÑÑейÑа бÑÑÑÑого доÑÑÑпа:
PGresult *PQfn(PGconn *conn,
int fnid,
int *result_buf,
int *result_len,
int result_is_int,
const PQArgBlock *args,
int nargs);
typedef struct
{
int len;
int isint;
union
{
int *ptr;
int integer;
} u;
} PQArgBlock;
ÐÑгÑÐ¼ÐµÐ½Ñ fnid пÑедÑÑавлÑÐµÑ Ñобой OID ÑÑнкÑии, коÑоÑÐ°Ñ Ð¿Ð¾Ð´Ð»ÐµÐ¶Ð¸Ñ Ð²ÑполнениÑ. args и nargs опÑеделÑÑÑ Ð¿Ð°ÑамеÑÑÑ, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÐµÑÐµÐ´Ð°Ð½Ñ ÑÑой ÑÑнкÑии; они Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ ÑпиÑÐºÑ Ð°ÑгÑменÑов обÑÑвленной ÑÑнкÑии. Ðогда поле isint ÑÑÑÑкÑÑÑÑ, пеÑедаваемой в каÑеÑÑве паÑамеÑÑа, Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение true, Ñогда знаÑение u.integer пеÑедаÑÑÑÑ ÑеÑвеÑÑ Ð² виде Ñелого ÑиÑла Ñказанной Ð´Ð»Ð¸Ð½Ñ (ÑÑо должно бÑÑÑ 2 или 4 байÑа); пÑи ÑÑом ÑÑÑанавливаеÑÑÑ Ð½ÑжнÑй поÑÑдок байÑов. Ðогда isint Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение false, Ñогда Ñказанное ÑиÑло Ð±Ð°Ð¹Ñ Ð¿Ð¾ адÑеÑÑ *u.ptr оÑпÑавлÑеÑÑÑ Ð±ÐµÐ· какой-либо обÑабоÑки; даннÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð² ÑоÑмаÑе, коÑоÑого Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ ÑеÑÐ²ÐµÑ Ð´Ð»Ñ Ð¿ÐµÑедаÑи в двоиÑном виде даннÑÑ
Ñого Ñипа, ÑÑо и аÑгÑменÑÑ ÑÑнкÑии. (ÐбÑÑвление Ð¿Ð¾Ð»Ñ u.ptr, как имеÑÑего Ñип int *, ÑвлÑеÑÑÑ Ð¸ÑÑоÑиÑеÑким; бÑло Ð±Ñ Ð»ÑÑÑе ÑаÑÑмаÑÑиваÑÑ ÐµÐ³Ð¾ как Ñип void *.) result_buf ÑказÑÐ²Ð°ÐµÑ Ð½Ð° бÑÑеÑ, в коÑоÑÑй должно бÑÑÑ Ð¿Ð¾Ð¼ÐµÑено возвÑаÑаемое знаÑение ÑÑнкÑии. ÐÑзÑваÑÑий код должен вÑделиÑÑ Ð´Ð¾ÑÑаÑоÑное меÑÑо Ð´Ð»Ñ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑаемого знаÑениÑ. (ÐÑо никак не пÑовеÑÑеÑÑÑ!) ФакÑиÑеÑÐºÐ°Ñ Ð´Ð»Ð¸Ð½Ð° ÑезÑлÑÑиÑÑÑÑего знаÑÐµÐ½Ð¸Ñ Ð² байÑаÑ
бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑена в пеÑеменной Ñелого Ñипа, на коÑоÑÑÑ ÑказÑÐ²Ð°ÐµÑ result_len. ÐÑли ожидаеÑÑÑ Ð¿Ð¾Ð»ÑÑение двÑÑ
- или ÑеÑÑÑÑÑ
байÑового ÑелоÑиÑленного ÑезÑлÑÑаÑа, Ñо пÑиÑвойÑе паÑамеÑÑÑ result_is_int знаÑение 1, в пÑоÑивном ÑлÑÑае назнаÑÑÑе ÐµÐ¼Ñ 0. Ðогда паÑамеÑÑ result_is_int Ñавен 1, libpq пеÑеÑÑавлÑÐµÑ Ð±Ð°Ð¹ÑÑ Ð² пеÑедаваемом знаÑении, еÑли ÑÑо необÑ
одимо, Ñак, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¾ бÑло доÑÑавлено на клиенÑÑкÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ Ð² виде пÑавилÑного знаÑÐµÐ½Ð¸Ñ Ñипа int; обÑаÑиÑе внимание, ÑÑо по адÑеÑÑ *result_buf доÑÑавлÑеÑÑÑ ÑеÑÑÑÑÑ
байÑовое Ñелое Ð´Ð»Ñ Ð»Ñбого допÑÑÑимого ÑазмеÑа ÑезÑлÑÑаÑа. Ðогда result_is_int Ñавен 0, Ñогда ÑÑÑока байÑов в двоиÑном ÑоÑмаÑе, оÑпÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ ÑеÑвеÑом, бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑена немодиÑиÑиÑованной. (Ð ÑÑом ÑлÑÑае лÑÑÑе ÑаÑÑмаÑÑиваÑÑ result_buf как имеÑÑий Ñип void *.)
PQfn вÑегда возвÑаÑÐ°ÐµÑ Ð´ÐµÐ¹ÑÑвиÑелÑнÑй ÑказаÑÐµÐ»Ñ Ð½Ð° обÑÐµÐºÑ PGresult Ñо ÑÑаÑÑÑом PGRES_COMMAND_OK пÑи ÑÑпеÑном вÑполнении ÑÑнкÑии или PGRES_FATAL_ERROR, еÑли пÑоизоÑла какаÑ-Ñо оÑибка. ÐеÑед иÑполÑзованием ÑезÑлÑÑаÑа нÑжно ÑнаÑала пÑовеÑиÑÑ ÐµÐ³Ð¾ ÑÑаÑÑÑ. ÐÑзÑваÑÑÐ°Ñ ÑÑнкÑÐ¸Ñ Ð¾ÑвеÑÐ°ÐµÑ Ð·Ð° оÑвобождение памÑÑи, занимаемой обÑекÑом PGresult, когда он болÑÑе не нÑжен, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ PQclear.
ЧÑÐ¾Ð±Ñ Ð¿ÐµÑедаÑÑ ÑÑнкÑии аÑгÑÐ¼ÐµÐ½Ñ NULL, запиÑиÑе в поле len ÑÑой ÑÑÑÑкÑÑÑÑ Ð·Ð½Ð°Ñение -1; Ð¿Ð¾Ð»Ñ isint и u в ÑÑом ÑлÑÑае не важнÑ. (Ðо ÑÑо ÑабоÑÐ°ÐµÑ ÑолÑко пÑи подклÑÑении по пÑоÑÐ¾ÐºÐ¾Ð»Ñ 3.0 и новее.)
ÐÑли ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ NULL, в *result_len запиÑÑваеÑÑÑ -1, а *result_buf не изменÑеÑÑÑ. (ÐÑо ÑабоÑÐ°ÐµÑ ÑолÑко пÑи подклÑÑении по пÑоÑÐ¾ÐºÐ¾Ð»Ñ 3.0 и новее; в пÑоÑоколе 2.0 ни *result_len, ни *result_buf не изменÑеÑÑÑ.)
ÐбÑаÑиÑе внимание, ÑÑо пÑи иÑполÑзовании ÑÑого инÑеÑÑейÑа невозможно обÑабоÑаÑÑ Ð¼Ð½Ð¾Ð¶ÐµÑÑва знаÑений в ÑезÑлÑÑаÑе. ÐÑоме Ñого, ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° бÑÑÑ Ð¾Ð±ÑÑной ÑÑнкÑией, а не пÑоÑедÑÑой, агÑегаÑной или оконной ÑÑнкÑией.