35.7. ÐÑполÑзование облаÑÑей деÑкÑипÑоÑов #
ÐблаÑÑи деÑкÑипÑоÑов SQL даÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ Ñложной обÑабоÑки ÑезÑлÑÑаÑов опеÑаÑоÑов SELECT, FETCH и DESCRIBE. ÐблаÑÑÑ Ð´ÐµÑкÑипÑоÑа SQL обÑединÑÐµÑ Ð² одной ÑÑÑÑкÑÑÑе даннÑе одной ÑÑÑоки и ÑлеменÑÑ Ð¼ÐµÑаданнÑÑ
. ÐÑи меÑаданнÑе оÑобенно Ð¿Ð¾Ð»ÐµÐ·Ð½Ñ Ð¿Ñи вÑполнении динамиÑеÑкиÑ
SQL-опеÑаÑоÑов, когда Ñ
аÑакÑÐµÑ ÑезÑлÑÑиÑÑÑÑиÑ
ÑÑолбÑов Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÐ¸Ð·Ð²ÐµÑÑен заÑанее. Postgres Pro пÑÐµÐ´Ð»Ð°Ð³Ð°ÐµÑ Ð´Ð²Ð° подÑ
ода к иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±Ð»Ð°ÑÑей деÑкÑипÑоÑов: именованнÑе облаÑÑи SQL-деÑкÑипÑоÑов и облаÑÑи SQLDA в ÑÑÑÑкÑÑÑаÑ
C.
35.7.1. ÐменованнÑе облаÑÑи SQL-деÑкÑипÑоÑов #
ÐÐ¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑÑ SQL-деÑкÑипÑоÑа ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· заголовка, ÑодеÑжаÑего ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð±Ð¾ вÑÑм деÑкÑипÑоÑе, и одного или неÑколÑÐºÐ¸Ñ Ð´ÐµÑкÑипÑоÑов ÑлеменÑов, коÑоÑÑе по ÑÑÑи опиÑÑваÑÑ Ð¾ÑделÑнÑе ÑÑолбÑÑ Ð² ÑÑÑоке ÑезÑлÑÑаÑа.
ÐÑежде Ñем Ð²Ñ ÑможеÑе иÑполÑзоваÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ SQL-деÑкÑипÑоÑа, ÐµÑ Ð½Ñжно вÑделиÑÑ:
EXEC SQL ALLOCATE DESCRIPTOR иденÑиÑикаÑоÑ;ÐаданнÑй иденÑиÑикаÑÐ¾Ñ Ð¸Ð³ÑÐ°ÐµÑ ÑÐ¾Ð»Ñ Â«Ð¸Ð¼ÐµÐ½Ð¸ пеÑеменной» облаÑÑи деÑкÑипÑоÑа. Ðогда деÑкÑипÑÐ¾Ñ Ð¾ÐºÐ°Ð·ÑваеÑÑÑ Ð½ÐµÐ½ÑжнÑм, его ÑледÑÐµÑ Ð¾ÑвободиÑÑ:
EXEC SQL DEALLOCATE DESCRIPTOR иденÑиÑикаÑоÑ;ЧÑÐ¾Ð±Ñ Ð²Ð¾ÑполÑзоваÑÑÑÑ Ð¾Ð±Ð»Ð°ÑÑÑÑ Ð´ÐµÑкÑипÑоÑа, ÐµÑ Ð½Ñжно ÑказаÑÑ Ð² каÑеÑÑве Ñелевого обÑекÑа в пÑедложении INTO, вмеÑÑо пеÑеÑиÑÐ»ÐµÐ½Ð¸Ñ Ð¿ÐµÑеменнÑÑ
ÑÑедÑ:
EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;
ÐÑли Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов пÑÑÑ, в облаÑÑи деÑкÑипÑоÑа бÑдÑÑ Ñем не менее ÑодеÑжаÑÑÑÑ Ð¼ÐµÑаданнÑе из запÑоÑа, Ñо еÑÑÑ Ð¸Ð¼ÐµÐ½Ð° полей.
ÐолÑÑиÑÑ Ð¼ÐµÑаданнÑе набоÑа ÑезÑлÑÑаÑов Ð´Ð»Ñ ÐµÑÑ Ð½Ðµ вÑполненнÑÑ
подгоÑовленнÑÑ
запÑоÑов можно, воÑполÑзовавÑиÑÑ Ð¾Ð¿ÐµÑаÑоÑом DESCRIBE:
EXEC SQL BEGIN DECLARE SECTION; char *sql_stmt = "SELECT * FROM table1"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE stmt1 FROM :sql_stmt; EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
Ðо PostgreSQL веÑÑии 9.0 клÑÑевое Ñлово SQL бÑло необÑзаÑелÑнÑм, Ñак ÑÑо пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ DESCRIPTOR и SQL DESCRIPTOR Ñоздавали именованнÑе облаÑÑи SQL-деÑкÑипÑоÑов. ТепеÑÑ Ð¾Ð½Ð¾ ÑÑало обÑзаÑелÑнÑм; без Ñлова SQL ÑоздаÑÑÑÑ Ð¾Ð±Ð»Ð°ÑÑи SQLDA, Ñм. ÐодÑаздел 35.7.2.
РопеÑаÑоÑаÑ
DESCRIBE и FETCH клÑÑевÑе Ñлова INTO и USING дейÑÑвÑÑÑ Ð¿ÑимеÑно одинаково: они ÑказÑваÑÑ Ð²ÑвеÑÑи Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов и меÑаданнÑе в облаÑÑÑ Ð´ÐµÑкÑипÑоÑа.
ÐÐ¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð²Ð¾Ð¿ÑоÑ: а как же полÑÑиÑÑ Ð´Ð°Ð½Ð½Ñе из облаÑÑи деÑкÑипÑоÑа? ÐблаÑÑÑ Ð´ÐµÑкÑипÑоÑа можно пÑедÑÑавиÑÑ ÐºÐ°Ðº ÑÑÑÑкÑÑÑÑ Ñ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ñми полÑми. ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð·Ð½Ð°Ñение Ð¿Ð¾Ð»Ñ Ð¸Ð· заголовка и ÑÐ¾Ñ ÑаниÑÑ ÐµÐ³Ð¾ в пеÑеменной ÑÑÐµÐ´Ñ C, нÑжно вÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ:
EXEC SQL GET DESCRIPTORимÑ:пеÑеменнаÑ_ÑÑедÑ=поле;
РнаÑÑоÑÑее вÑÐµÐ¼Ñ Ð¾Ð¿Ñеделено ÑолÑко одно поле заголовка: COUNT, коÑоÑое говоÑиÑ, ÑколÑко облаÑÑей деÑкÑипÑоÑов ÑлеменÑов ÑÑÑеÑÑвÑÐµÑ (Ñо еÑÑÑ, ÑколÑко ÑÑолбÑов ÑодеÑжиÑÑÑ Ð² ÑезÑлÑÑаÑе). ÐеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑÑÐµÐ´Ñ C должна имеÑÑ ÑелоÑиÑленнÑй Ñип. ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¿Ð¾Ð»Ðµ из облаÑÑи деÑкÑипÑоÑа ÑлеменÑа, нÑжно вÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ:
EXEC SQL GET DESCRIPTORимÑVALUEномеÑ:пеÑеменнаÑ_ÑÑедÑ=поле;
РкаÑеÑÑве num можно задаÑÑ Ð¾Ð±ÑÑное Ñелое или пеÑеменнÑÑ ÑÑÐµÐ´Ñ C, ÑодеÑжаÑÑÑ Ñелое ÑиÑло. ÐопÑÑÑимÑе полÑ:
CARDINALITY(integer) #ÑиÑло ÑÑÑок в набоÑе ÑезÑлÑÑаÑов
DATA#ÑобÑÑвенно ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð´Ð°Ð½Ð½ÑÑ (Ñип даннÑÑ Ð¿Ð¾Ð»Ñ Ð·Ð°Ð²Ð¸ÑÐ¸Ñ Ð¾Ñ Ð·Ð°Ð¿ÑоÑа)
DATETIME_INTERVAL_CODE(Ñелое) #Ðогда
TYPEÑавно9,DATETIME_INTERVAL_CODEÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°Ñение1длÑDATE,2длÑTIME,3длÑTIMESTAMP,4длÑTIME WITH TIME ZONE, либо5длÑTIMESTAMP WITH TIME ZONE.DATETIME_INTERVAL_PRECISION(Ñелое) #не Ñеализовано
INDICATOR(Ñелое) #индикаÑÐ¾Ñ (оÑмеÑаÑÑий знаÑение NULL или ÑÑеÑение знаÑениÑ)
KEY_MEMBER(Ñелое) #не Ñеализовано
LENGTH(Ñелое) #длина даннÑÑ Ð² ÑимволаÑ
NAME(ÑÑÑока) #Ð¸Ð¼Ñ ÑÑолбÑа
NULLABLE(Ñелое) #не Ñеализовано
OCTET_LENGTH(Ñелое) #длина ÑимволÑного пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð² байÑаÑ
PRECISION(Ñелое) #ÑоÑноÑÑÑ (Ð´Ð»Ñ Ñипа
numeric)RETURNED_LENGTH(Ñелое) #длина даннÑÑ Ð² ÑимволаÑ
RETURNED_OCTET_LENGTH(Ñелое) #длина ÑимволÑного пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð² байÑаÑ
SCALE(Ñелое) #маÑÑÑаб (Ð´Ð»Ñ Ñипа
numeric)TYPE(Ñелое) #ÑиÑловой код Ñипа даннÑÑ ÑÑолбÑа
РопеÑаÑоÑаÑ
EXECUTE, DECLARE и OPEN клÑÑевÑе Ñлова INTO и USING дейÑÑвÑÑÑ Ð¿Ð¾-ÑазномÑ. ÐблаÑÑÑ Ð´ÐµÑкÑипÑоÑа Ñакже можно ÑÑоÑмиÑоваÑÑ Ð²ÑÑÑнÑÑ, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑедаÑÑ Ð²Ñ
однÑе паÑамеÑÑÑ Ð·Ð°Ð¿ÑоÑÑ Ð¸Ð»Ð¸ кÑÑÑоÑÑ, а команда USING SQL DESCRIPTOR даÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¿ÐµÑедаÑÑ Ð²Ñ
однÑе аÑгÑменÑÑ Ð¿Ð°ÑамеÑÑÐ¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿ÑоÑÑ. ÐпеÑаÑоÑ, ÑоÑмиÑÑÑÑий именованнÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ SQL-деÑкÑипÑоÑа, вÑглÑÐ´Ð¸Ñ Ñак: имÑ
EXEC SQL SET DESCRIPTORимÑVALUEномеÑполе= :пеÑеменнаÑ_ÑÑедÑ;
Postgres Pro поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð²ÑбоÑÐºÑ ÑÑÐ°Ð·Ñ Ð½ÐµÑколÑкиÑ
запиÑей в одном опеÑаÑоÑе FETCH и Ð¼Ð¾Ð¶ÐµÑ ÑоÑ
ÑаниÑÑ Ð¸Ñ
даннÑе в пеÑеменной ÑÑÐµÐ´Ñ Ð¡, еÑли ÑÑа пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ â маÑÑив. ÐапÑимеÑ:
EXEC SQL BEGIN DECLARE SECTION; int id[5]; EXEC SQL END DECLARE SECTION; EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc; EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;
35.7.2. ÐблаÑÑи деÑкÑипÑоÑов SQLDA #
ÐблаÑÑÑ Ð´ÐµÑкÑипÑоÑа SQLDA пÑедÑÑавлÑÐµÑ Ñобой ÑÑÑÑкÑÑÑÑ ÑзÑка C, в коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов и меÑаданнÑе запÑоÑа. Ðдна ÑÐ°ÐºÐ°Ñ ÑÑÑÑкÑÑÑа ÑодеÑÐ¶Ð¸Ñ Ð¾Ð´Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð· набоÑа даннÑÑ .
EXEC SQL include sqlda.h; sqlda_t *mysqlda; EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;
ÐамеÑÑÑе, ÑÑо клÑÑевое Ñлово SQL в ÑÑом ÑлÑÑае опÑÑкаеÑÑÑ. ÐамеÑÐ°Ð½Ð¸Ñ Ð¾ÑноÑиÑелÑно пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ»ÑÑевÑÑ
Ñлов INTO и USING в ÐодÑазделе 35.7.1 пÑÐ¸Ð¼ÐµÐ½Ð¸Ð¼Ñ Ð¸ здеÑÑ, Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸ÐµÐ¼. РопеÑаÑоÑе DESCRIBE можно полноÑÑÑÑ Ð¾Ð¿ÑÑÑиÑÑ ÐºÐ»ÑÑевое Ñлово DESCRIPTOR, еÑли пÑиÑÑÑÑÑвÑÐµÑ ÐºÐ»ÑÑевое Ñлово INTO:
EXEC SQL DESCRIBE prepared_statement INTO mysqlda;
ÐбÑÐ°Ñ ÑÑ ÐµÐ¼Ð° иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ SQLDA вÑглÑÐ´Ð¸Ñ Ñак:
ÐодгоÑовиÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¸ обÑÑвиÑÑ ÐºÑÑÑÐ¾Ñ Ð´Ð»Ñ Ð½ÐµÐ³Ð¾.
ÐбÑÑвиÑÑ SQLDA Ð´Ð»Ñ ÑÑÑок ÑезÑлÑÑаÑа.
ÐбÑÑвиÑÑ SQLDA Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð¿Ð°ÑамеÑÑов и иниÑиализиÑоваÑÑ Ð¸Ñ (вÑделиÑÑ Ð¿Ð°Ð¼ÑÑÑ, задаÑÑ Ð¿Ð°ÑамеÑÑÑ).
ÐÑкÑÑÑÑ ÐºÑÑÑÐ¾Ñ Ñ Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA.
ÐÑбÑаÑÑ ÑÑÑоки из кÑÑÑоÑа и ÑÐ¾Ñ ÑаниÑÑ Ð¸Ñ Ð² вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA.
ÐÑоÑиÑаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð· вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA в пеÑеменнÑе ÑÑÐµÐ´Ñ (и пÑеобÑазоваÑÑ Ð¿Ñи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи).
ÐакÑÑÑÑ ÐºÑÑÑоÑ.
ÐÑвободиÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð¿Ð°Ð¼ÑÑи, вÑделеннÑÑ Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA.
35.7.2.1. СÑÑÑкÑÑÑа даннÑÑ SQLDA #
ÐÐ»Ñ SQLDA иÑполÑзÑÑÑÑÑ ÑÑи Ñипа даннÑÑ
: sqlda_t, sqlvar_t и struct sqlname.
ÐодÑказка
СÑÑÑкÑÑÑа даннÑÑ SQLDA в Postgres Pro подобна Ñой, ÑÑо иÑполÑзÑеÑÑÑ Ð² IBM DB2 Universal Database, Ñак ÑÑо ÑаÑÑÑ ÑÐµÑ Ð½Ð¸ÑеÑкой инÑоÑмаÑии по SQLDA в DB2 Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° и Ð´Ð»Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸Ñ ÑÑÑÑойÑÑва SQLDA в Postgres Pro.
35.7.2.1.1. СÑÑÑкÑÑÑа sqlda_t #
Тип ÑÑÑÑкÑÑÑÑ sqlda_t пÑедÑÑавлÑÐµÑ Ñип ÑобÑÑвенно SQLDA. ÐÑа ÑÑÑÑкÑÑÑа опиÑÑÐ²Ð°ÐµÑ Ð¾Ð´Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑ. Ðве или более ÑÑÑÑкÑÑÑ sqlda_t могÑÑ Ð¾Ð±ÑединÑÑÑÑÑ Ð² ÑвÑзаннÑй ÑпиÑок по ÑказаÑелÑм в поле desc_next, и Ñаким обÑазом обÑазовÑваÑÑ ÑпоÑÑдоÑеннÑй Ð½Ð°Ð±Ð¾Ñ ÑÑÑок. ÐоÑÑомÑ, когда вÑбиÑаÑÑÑÑ Ð´Ð²Ðµ или более ÑÑÑок, пÑиложение Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑиÑаÑÑ Ð¸Ñ
, пÑоÑледÑÑ Ð¿Ð¾ ÑказаÑелÑм desc_next во вÑеÑ
ÑзлаÑ
sqlda_t.
Тип sqlda_t опÑеделÑеÑÑÑ Ñак:
struct sqlda_struct
{
char sqldaid[8];
long sqldabc;
short sqln;
short sqld;
struct sqlda_struct *desc_next;
struct sqlvar_struct sqlvar[1];
};
typedef struct sqlda_struct sqlda_t;Ðго Ð¿Ð¾Ð»Ñ Ð¸Ð¼ÐµÑÑ ÑледÑÑÑее назнаÑение:
sqldaid#СодеÑÐ¶Ð¸Ñ ÑÑÑоковÑÑ ÐºÐ¾Ð½ÑÑанÑÑ
"SQLDA ".sqldabc#СодеÑÐ¶Ð¸Ñ ÑÐ°Ð·Ð¼ÐµÑ Ð²Ñделенного пÑоÑÑÑанÑÑва в байÑÐ°Ñ .
sqln#СодеÑÐ¶Ð¸Ñ ÑиÑло Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð¿Ð°ÑамеÑÑов Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑизованного запÑоÑа, когда пеÑедаÑÑÑÑ Ð² опеÑаÑоÑÑ
OPEN,DECLAREилиEXECUTEÑ ÐºÐ»ÑÑевÑм ÑловомUSING. Ð ÑÑÑÑкÑÑÑе, вÑводимой опеÑаÑоÑамиSELECT,EXECUTEилиFETCH, данное знаÑение ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ Ñsqld.sqld#СодеÑÐ¶Ð¸Ñ ÑиÑло полей в набоÑе ÑезÑлÑÑаÑов.
desc_next#ÐÑли запÑÐ¾Ñ Ð²ÑдаÑÑ Ð½ÐµÑколÑко запиÑей, возвÑаÑаеÑÑÑ Ð½ÐµÑколÑко ÑвÑзаннÑÑ ÑÑÑÑкÑÑÑ SQLDA, а
desc_nextÑодеÑÐ¶Ð¸Ñ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑледÑÑÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð² ÑпиÑке.sqlvar#ÐÑо маÑÑив ÑÑолбÑов в набоÑе ÑезÑлÑÑаÑов.
35.7.2.1.2. СÑÑÑкÑÑÑа sqlvar_t #
Тип ÑÑÑÑкÑÑÑÑ sqlvar_t ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°Ñение ÑÑолбÑа и меÑаданнÑе, в ÑаÑÑноÑÑи, Ñип и длинÑ. ÐÑа ÑÑÑÑкÑÑÑа опÑеделÑеÑÑÑ Ñак:
struct sqlvar_struct
{
short sqltype;
short sqllen;
char *sqldata;
short *sqlind;
struct sqlname sqlname;
};
typedef struct sqlvar_struct sqlvar_t;ÐÑ Ð¿Ð¾Ð»Ñ Ð¸Ð¼ÐµÑÑ ÑледÑÑÑее назнаÑение:
sqltype#СодеÑÐ¶Ð¸Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¾Ñ Ñипа данного полÑ. ÐозможнÑе знаÑÐµÐ½Ð¸Ñ Ð¿ÐµÑеÑиÑÐ»ÐµÐ½Ñ Ð²
enum ECPGttypeвecpgtype.h.sqllen#СодеÑÐ¶Ð¸Ñ Ð´Ð²Ð¾Ð¸ÑнÑÑ Ð´Ð»Ð¸Ð½Ñ Ð¿Ð¾Ð»Ñ, напÑÐ¸Ð¼ÐµÑ 4 байÑа длÑ
ECPGt_int.sqldata#УказÑÐ²Ð°ÐµÑ Ð½Ð° даннÑе. ФоÑÐ¼Ð°Ñ Ð´Ð°Ð½Ð½ÑÑ Ð¾Ð¿Ð¸Ñан в ÐодÑазделе 35.4.4.
sqlind#УказÑÐ²Ð°ÐµÑ Ð½Ð° индикаÑÐ¾Ñ NULL. 0 ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð½Ðµ NULL, -1 â NULL.
sqlname#ÐÐ¼Ñ Ð¿Ð¾Ð»Ñ.
35.7.2.1.3. СÑÑÑкÑÑÑа struct sqlname #
СÑÑÑкÑÑÑа struct sqlname ÑодеÑÐ¶Ð¸Ñ Ð¸Ð¼Ñ ÑÑолбÑа. Ðна вклÑÑена в sqlvar_t в каÑеÑÑве Ñлена. ÐÑа ÑÑÑÑкÑÑÑа опÑеделена Ñак:
#define NAMEDATALEN 64
struct sqlname
{
short length;
char data[NAMEDATALEN];
};ÐÑ Ð¿Ð¾Ð»Ñ Ð¸Ð¼ÐµÑÑ ÑледÑÑÑее назнаÑение:
35.7.2.2. ÐолÑÑение набоÑа ÑезÑлÑÑаÑов Ñ Ð¿Ñименением SQLDA #
ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов запÑоÑа ÑеÑез SQLDA, нÑжно пÑоделаÑÑ Ð¿ÑимеÑно ÑледÑÑÑее:
ÐбÑÑвиÑÑ ÑÑÑÑкÑÑÑÑ
sqlda_tÐ´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ Ð½Ð°Ð±Ð¾Ñа ÑезÑлÑÑаÑов.ÐÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ
FETCH/EXECUTE/DESCRIBEÐ´Ð»Ñ Ð¾Ð±ÑабоÑки запÑоÑа Ñ Ñказанной SQLDA.ÐпÑеделиÑÑ ÑиÑло запиÑей в набоÑе ÑезÑлÑÑаÑов, пÑоÑиÑав
sqln, Ñлен ÑÑÑÑкÑÑÑÑsqlda_t.ÐолÑÑиÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑÑолбÑа из ÑлеменÑов
sqlvar[0],sqlvar[1]и Ñ. д., ÑоÑÑавлÑÑÑÐ¸Ñ Ð¼Ð°ÑÑив, вклÑÑÑннÑй в ÑÑÑÑкÑÑÑÑsqlda_t.ÐеÑейÑи к ÑледÑÑÑей ÑÑÑоке (ÑÑÑÑкÑÑÑе
sqlda_t) по ÑказаÑелÑdesc_next, ÑÐ»ÐµÐ½Ñ ÑÑÑÑкÑÑÑÑsqlda_t.ÐÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи повÑоÑиÑÑ ÑÑи дейÑÑвиÑ.
Ðалее показÑваеÑÑÑ, как полÑÑиÑÑ Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов ÑеÑез SQLDA.
СнаÑала обÑÑвиÑе ÑÑÑÑкÑÑÑÑ sqlda_t, в коÑоÑÑÑ Ð±ÑÐ´ÐµÑ Ð¿Ð¾Ð¼ÐµÑÑн Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов.
sqlda_t *sqlda1;
ÐаÑем ÑкажиÑе ÑÑÑ SQLDA в команде. Рданном пÑимеÑе ÑÑо команда FETCH.
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
ÐбÑабоÑайÑе вÑе ÑÑÑоки в Ñикле Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´Ð¾Ð¼ по ÑвÑÐ·Ð°Ð½Ð½Ð¾Ð¼Ñ ÑпиÑкÑ.
sqlda_t *cur_sqlda;
for (cur_sqlda = sqlda1;
cur_sqlda != NULL;
cur_sqlda = cur_sqlda->desc_next)
{
...
}ÐнÑÑÑи ÑÑого Ñикла ÑеализÑйÑе еÑÑ Ð¾Ð´Ð¸Ð½ Ñикл ÑÑÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
каждого ÑÑолбÑа (ÑÑÑÑкÑÑÑÑ sqlvar_t) в ÑÑÑоке.
for (i = 0; i < cur_sqlda->sqld; i++)
{
sqlvar_t v = cur_sqlda->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
...
}ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð·Ð½Ð°Ñение ÑÑолбÑа, пÑоÑиÑайÑе знаÑение Ð¿Ð¾Ð»Ñ sqltype, Ñлена ÑÑÑÑкÑÑÑÑ sqlvar_t. ÐаÑем вÑбеÑиÑе подÑ
одÑÑий ÑпоÑоб, в завиÑимоÑÑи Ð¾Ñ Ñипа ÑÑолбÑа, копиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
из Ð¿Ð¾Ð»Ñ sqlvar в пеÑеменнÑÑ ÑÑÐµÐ´Ñ Ð¡.
char var_buf[1024];
switch (v.sqltype)
{
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf) - 1 : sqllen));
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
...
}35.7.2.3. ÐеÑедаÑа знаÑений паÑамеÑÑов ÑеÑез SQLDA #
ЧÑÐ¾Ð±Ñ Ð¿ÐµÑедаÑÑ Ð¿Ð°ÑамеÑÑÑ Ð¿Ð¾Ð´Ð³Ð¾ÑÐ¾Ð²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿ÑоÑÑ ÑеÑез SQLDA, нÑжно пÑоделаÑÑ Ð¿ÑимеÑно ÑледÑÑÑее:
СоздаÑÑ Ð¿Ð¾Ð´Ð³Ð¾ÑовленнÑй запÑÐ¾Ñ (подгоÑовленнÑй опеÑаÑоÑ)
ÐбÑÑвиÑÑ ÑÑÑÑкÑÑÑÑ sqlda_t в каÑеÑÑве Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA.
ÐÑделиÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð¿Ð°Ð¼ÑÑи (ÑÑÑÑкÑÑÑÑ sqlda_t) Ð´Ð»Ñ Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ SQLDA.
УÑÑановиÑÑ (ÑкопиÑоваÑÑ) Ð²Ñ Ð¾Ð´Ð½Ñе знаÑÐµÐ½Ð¸Ñ Ð² вÑделенной памÑÑи.
ÐÑкÑÑÑÑ ÐºÑÑÑоÑ, Ñказав Ð²Ñ Ð¾Ð´Ð½ÑÑ SQLDA.
РаÑÑмоÑÑим ÑÑо на пÑимеÑе.
СнаÑала ÑоздайÑе подгоÑовленнÑй опеÑаÑоÑ.
EXEC SQL BEGIN DECLARE SECTION; char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE stmt1 FROM :query;
ÐаÑем вÑделиÑе памÑÑÑ Ð´Ð»Ñ SQLDA и ÑÑÑановиÑе ÑиÑло вÑ
однÑÑ
паÑамеÑÑов в поле sqln, Ñлене ÑÑÑÑкÑÑÑÑ sqlda_t. Ðогда Ð´Ð»Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного запÑоÑа ÑÑебÑÑÑÑÑ Ð´Ð²Ð° или более вÑ
однÑÑ
паÑамеÑÑов, пÑиложение должно вÑделиÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑное меÑÑо в памÑÑи, ÑÐ°Ð·Ð¼ÐµÑ ÐºÐ¾ÑоÑого вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº (ÑиÑло паÑамеÑÑов - 1) * sizeof(sqlvar_t). Рпоказанном здеÑÑ Ð¿ÑимеÑе вÑделÑеÑÑÑ Ð¼ÐµÑÑо Ð´Ð»Ñ Ð´Ð²ÑÑ
паÑамеÑÑов.
sqlda_t *sqlda2; sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t)); memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t)); sqlda2->sqln = 2; /* ÑиÑло Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð¿ÐµÑеменнÑÑ */
ÐÑделив памÑÑÑ, ÑоÑ
ÑаниÑе знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов в маÑÑиве sqlvar[]. (ÐÑÐ¾Ñ Ð¶Ðµ маÑÑив иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð·Ð½Ð°Ñений ÑÑолбÑов, когда SQLDA полÑÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾Ñ ÑезÑлÑÑаÑов.) Рданном пÑимеÑе пеÑедаÑÑÑÑ Ð´Ð²Ð° паÑамеÑÑа: "postgres" (ÑÑÑокового Ñипа) и 1 (ÑелоÑиÑленного Ñипа).
sqlda2->sqlvar[0].sqltype = ECPGt_char; sqlda2->sqlvar[0].sqldata = "postgres"; sqlda2->sqlvar[0].sqllen = 8; int intval = 1; sqlda2->sqlvar[1].sqltype = ECPGt_int; sqlda2->sqlvar[1].sqldata = (char *) &intval; sqlda2->sqlvar[1].sqllen = sizeof(intval);
ÐÑкÑойÑе кÑÑÑÐ¾Ñ Ñ Ñказанием Ñанее Ñозданной SQLDA, ÑÑÐ¾Ð±Ñ Ð²Ñ Ð¾Ð´Ð½Ñе паÑамеÑÑÑ Ð±Ñли пеÑÐµÐ´Ð°Ð½Ñ Ð¿Ð¾Ð´Ð³Ð¾ÑÐ¾Ð²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ Ð¾Ð¿ÐµÑаÑоÑÑ.
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
ÐаконеÑ, законÑив иÑполÑзование Ð²Ñ Ð¾Ð´Ð½ÑÑ SQLDA, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ Ñвно оÑвободиÑÑ Ð²ÑделеннÑÑ Ð´Ð»Ñ Ð½Ð¸Ñ Ð¿Ð°Ð¼ÑÑÑ, в оÑлиÑие Ð¾Ñ SQLDA, полÑÑаÑÑÐ¸Ñ ÑезÑлÑÑаÑÑ Ð·Ð°Ð¿ÑоÑов.
free(sqlda2);
35.7.2.4. ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑиложениÑ, иÑполÑзÑÑÑего SQLDA #
ÐÑедÑÑавленнÑй здеÑÑ Ð¿ÑÐ¸Ð¼ÐµÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑ, как вÑбÑаÑÑ Ð¸Ð· ÑиÑÑемнÑÑ ÐºÐ°Ñалогов ÑÑаÑиÑÑÐ¸ÐºÑ Ð´Ð¾ÑÑÑпа к базам даннÑÑ , опÑеделÑннÑÑ Ð²Ñ Ð¾Ð´Ð½Ñми паÑамеÑÑами.
ÐÑо пÑиложение ÑоединÑÐµÑ Ð·Ð°Ð¿Ð¸Ñи двÑÑ
ÑиÑÑемнÑÑ
ÑаблиÑ, pg_database и pg_stat_database по OID Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
, и Ñакже вÑбиÑÐ°ÐµÑ Ð¸ показÑÐ²Ð°ÐµÑ ÑÑаÑиÑÑикÑ, пÑÐ¸Ð½Ð¸Ð¼Ð°Ñ Ð´Ð²Ð° вÑ
однÑÑ
паÑамеÑÑа (база даннÑÑ
postgres и OID 1).
СнаÑала ÑоздайÑе SQLDA Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ð° паÑамеÑÑов и SQLDA Ð´Ð»Ñ Ð²Ñвода ÑезÑлÑÑаÑов.
EXEC SQL include sqlda.h; sqlda_t *sqlda1; /* вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ деÑкÑипÑÐ¾Ñ */ sqlda_t *sqlda2; /* Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ деÑкÑипÑÐ¾Ñ */
ÐаÑем подклÑÑиÑеÑÑ Ðº базе даннÑÑ , подгоÑовÑÑе опеÑаÑÐ¾Ñ Ð¸ обÑÑвиÑе кÑÑÑÐ¾Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного опеÑаÑоÑа.
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO testdb AS con1 USER testuser;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
EXEC SQL PREPARE stmt1 FROM :query;
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;ÐаÑем запиÑиÑе некоÑоÑÑе знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов во вÑ
однÑÑ SQLDA. ÐÑделиÑе памÑÑÑ Ð´Ð»Ñ Ð²Ñ
одной SQLDA и ÑÑÑановиÑе колиÑеÑÑво паÑамеÑÑов в sqln. ÐапиÑиÑе Ñип, знаÑение и Ð´Ð»Ð¸Ð½Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð² Ð¿Ð¾Ð»Ñ sqltype, sqldata и sqllen ÑÑÑÑкÑÑÑÑ sqlvar.
/* СоздаÑÑ ÑÑÑÑкÑÑÑÑ SQLDA Ð´Ð»Ñ Ð²Ñ
однÑÑ
паÑамеÑÑов. */
sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
sqlda2->sqln = 2; /* ÑиÑло вÑ
однÑÑ
пеÑеменнÑÑ
*/
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *)&intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);ÐодгоÑовив Ð²Ñ Ð¾Ð´Ð½ÑÑ SQLDA, оÑкÑойÑе кÑÑÑÐ¾Ñ Ñ Ð½ÐµÐ¹.
/* ÐÑкÑÑÑÑ ÐºÑÑÑÐ¾Ñ Ñ Ð²Ñ
однÑми паÑамеÑÑами. */
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;ÐÑбеÑиÑе ÑÑÑоки из оÑкÑÑÑого кÑÑÑоÑа в вÑÑ
однÑÑ SQLDA. (ÐбÑÑно, ÑÑÐ¾Ð±Ñ Ð²ÑбÑаÑÑ Ð²Ñе ÑÑÑоки в набоÑе ÑезÑлÑÑаÑов, нÑжно повÑоÑÑÑÑ FETCH в Ñикле.)
while (1)
{
sqlda_t *cur_sqlda;
/* ÐазнаÑиÑÑ Ð´ÐµÑкÑипÑÐ¾Ñ ÐºÑÑÑоÑÑ */
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;ÐаÑем пÑоÑиÑайÑе вÑбÑаннÑе запиÑи из SQLDA, ÑледÑÑ Ð¿Ð¾ ÑвÑÐ·Ð°Ð½Ð½Ð¾Ð¼Ñ ÑпиÑÐºÑ ÑÑÑÑкÑÑÑÑ sqlda_t.
for (cur_sqlda = sqlda1 ;
cur_sqlda != NULL ;
cur_sqlda = cur_sqlda->desc_next)
{
...ÐÑоÑиÑайÑе вÑе ÑÑолбÑÑ Ð¿ÐµÑвой запиÑи. ÐолиÑеÑÑво ÑÑолбÑов Ñ
ÑаниÑÑÑ Ð² поле sqld, а даннÑе пеÑвого ÑÑолбÑа в sqlvar[0], оба ÑÑи Ð¿Ð¾Ð»Ñ â ÑÐ»ÐµÐ½Ñ ÑÑÑÑкÑÑÑÑ sqlda_t.
/* ÐÑвеÑÑи каждÑй ÑÑÐ¾Ð»Ð±ÐµÑ Ð² ÑÑÑоке. */
for (i = 0; i < sqlda1->sqld; i++)
{
sqlvar_t v = sqlda1->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
strncpy(name_buf, v.sqlname.data, v.sqlname.length);
name_buf[v.sqlname.length] = '\0';ТепеÑÑ Ð´Ð°Ð½Ð½Ñе ÑÑолбÑов ÑоÑ
ÑÐ°Ð½ÐµÐ½Ñ Ð² пеÑеменной v. СкопиÑÑйÑе вÑе ÑлеменÑÑ Ð´Ð°Ð½Ð½ÑÑ
в пеÑеменнÑе ÑÑедÑ, опÑеделив Ñип ÑÑолбÑа по Ð¿Ð¾Ð»Ñ v.sqltype.
switch (v.sqltype) {
int intval;
double doubleval;
unsigned long long int longlongval;
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf)-1 : sqllen));
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
...
default:
...
}
printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
}ÐаконÑив обÑабоÑÐºÑ Ð²ÑÐµÑ Ð·Ð°Ð¿Ð¸Ñей, закÑойÑе кÑÑÑÐ¾Ñ Ð¸ оÑклÑÑиÑеÑÑ Ð¾Ñ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ .
EXEC SQL CLOSE cur1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;ÐÑÑ Ð¿ÑогÑамма показана в ÐÑимеÑе 35.1.
ÐÑÐ¸Ð¼ÐµÑ 35.1. ÐÑÐ¸Ð¼ÐµÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð½Ð° базе SQLDA
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
EXEC SQL include sqlda.h;
sqlda_t *sqlda1; /* деÑкÑипÑÐ¾Ñ Ð´Ð»Ñ Ð²ÑÑ
однÑÑ
даннÑÑ
*/
sqlda_t *sqlda2; /* деÑкÑипÑÐ¾Ñ Ð´Ð»Ñ Ð²Ñ
однÑÑ
даннÑÑ
*/
EXEC SQL WHENEVER NOT FOUND DO BREAK;
EXEC SQL WHENEVER SQLERROR STOP;
int
main(void)
{
EXEC SQL BEGIN DECLARE SECTION;
char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
int intval;
unsigned long long int longlongval;
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
EXEC SQL PREPARE stmt1 FROM :query;
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
/* СоздаÑÑ ÑÑÑÑкÑÑÑÑ SQLDA Ð´Ð»Ñ Ð²Ñ
однÑÑ
паÑамеÑÑов */
sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
sqlda2->sqln = 2; /* ÑиÑло вÑ
однÑÑ
пеÑеменнÑÑ
*/
sqlda2->sqlvar[0].sqltype = ECPGt_char;
sqlda2->sqlvar[0].sqldata = "postgres";
sqlda2->sqlvar[0].sqllen = 8;
intval = 1;
sqlda2->sqlvar[1].sqltype = ECPGt_int;
sqlda2->sqlvar[1].sqldata = (char *) &intval;
sqlda2->sqlvar[1].sqllen = sizeof(intval);
/* ÐÑкÑÑÑÑ ÐºÑÑÑÐ¾Ñ Ñ Ð²Ñ
однÑми паÑамеÑÑами. */
EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
while (1)
{
sqlda_t *cur_sqlda;
/* ÐÑиÑвоиÑÑ Ð´ÐµÑкÑипÑÐ¾Ñ ÐºÑÑÑоÑÑ */
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
for (cur_sqlda = sqlda1 ;
cur_sqlda != NULL ;
cur_sqlda = cur_sqlda->desc_next)
{
int i;
char name_buf[1024];
char var_buf[1024];
/* ÐапеÑаÑаÑÑ ÐºÐ°Ð¶Ð´Ñй ÑÑÐ¾Ð»Ð±ÐµÑ Ð² ÑÑÑоке. */
for (i=0 ; i<cur_sqlda->sqld ; i++)
{
sqlvar_t v = cur_sqlda->sqlvar[i];
char *sqldata = v.sqldata;
short sqllen = v.sqllen;
strncpy(name_buf, v.sqlname.data, v.sqlname.length);
name_buf[v.sqlname.length] = '\0';
switch (v.sqltype)
{
case ECPGt_char:
memset(&var_buf, 0, sizeof(var_buf));
memcpy(&var_buf, sqldata, (sizeof(var_buf)<=sqllen ? sizeof(var_buf)-1 : sqllen) );
break;
case ECPGt_int: /* integer */
memcpy(&intval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%d", intval);
break;
case ECPGt_long_long: /* bigint */
memcpy(&longlongval, sqldata, sqllen);
snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
break;
default:
{
int i;
memset(var_buf, 0, sizeof(var_buf));
for (i = 0; i < sqllen; i++)
{
char tmpbuf[16];
snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]);
strncat(var_buf, tmpbuf, sizeof(var_buf));
}
}
break;
}
printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
}
printf("\n");
}
}
EXEC SQL CLOSE cur1;
EXEC SQL COMMIT;
EXEC SQL DISCONNECT ALL;
return 0;
}ÐÑвод ÑÑой пÑогÑÐ°Ð¼Ð¼Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ Ð¿ÑимеÑно Ñаким (некоÑоÑÑе ÑиÑла бÑдÑÑ Ð¼ÐµÐ½ÑÑÑÑÑ).
oid = 1 (type: 1)
datname = template1 (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = t (type: 1)
datallowconn = t (type: 1)
datconnlimit = -1 (type: 5)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig = (type: 1)
datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
datid = 1 (type: 1)
datname = template1 (type: 1)
numbackends = 0 (type: 5)
xact_commit = 113606 (type: 9)
xact_rollback = 0 (type: 9)
blks_read = 130 (type: 9)
blks_hit = 7341714 (type: 9)
tup_returned = 38262679 (type: 9)
tup_fetched = 1836281 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)
oid = 11511 (type: 1)
datname = postgres (type: 1)
datdba = 10 (type: 1)
encoding = 0 (type: 5)
datistemplate = f (type: 1)
datallowconn = t (type: 1)
datconnlimit = -1 (type: 5)
datfrozenxid = 379 (type: 1)
dattablespace = 1663 (type: 1)
datconfig = (type: 1)
datacl = (type: 1)
datid = 11511 (type: 1)
datname = postgres (type: 1)
numbackends = 0 (type: 5)
xact_commit = 221069 (type: 9)
xact_rollback = 18 (type: 9)
blks_read = 1176 (type: 9)
blks_hit = 13943750 (type: 9)
tup_returned = 77410091 (type: 9)
tup_fetched = 3253694 (type: 9)
tup_inserted = 0 (type: 9)
tup_updated = 0 (type: 9)
tup_deleted = 0 (type: 9)