Embedded SQL v C/C++ III pole, struktury Jindřich Vodrážka
Obsah referátu
● ● ● ● ● ● ● ● ●
Motivace k použití polí v emb. SQL Deklarace Host Arrays Použití polí v jednoduchých dotazech Použití polí ve složitějších dotazech Omezení při použití polí Struktury v emb. SQL Deklarace Host Structures Příklad použití struktur v SQL dotazech Multi-row & Multi-column operace
Motivace for(i=0; i< MAX; ++i) { EXEC SQL ... }
for(i=0; i< MAX; ++i) { /* naplneni pole */ } EXEC SQL ...
● ●
●
zjednodušení kódu programu redukce času spotřebovaného na komunikaci mezi klientským programem a serverem “masová” manipulace s daty
Deklarace Host Arrays EXEC MYSQL BEGIN DECLARE SECTION; VARCHAR names[20][21]; int salaries[20]; int ids[10]; /*(1) – ERROR */ int matrix[10][10]; /*(2) – ERROR */ EXEC MYSQL END DECLARE SECTION;
(1) v jednom SQL dotazu nelze použít pole různých velikostí (2) s výjimkou typu char nelze deklarovat vícedimenzionální pole
Použití v jednoduchých dotazech int maxid;
/* maximalni id z tabulky employees */
/* zaplneni poli */ int i; for(i=0; i<10; ++i) { printf("Zadejte jmeno:\n"); /* zde pro jednoduchost predpokladejme korektni vstup */ gets(names[i].arr); names[i].len = strlen(names[i].arr); ids[i]=maxid+i; } /* vkladani poli */ EXEC SQL INSERT INTO employees (id,name) VALUES(:ids,:names); EXEC SQL COMMIT WORK RELEASE;
Použití v jednoduchých dotazech ... /* zaplneni pozdeji vyuzitych poli */ /* priklad pro UPDATE */ EXEC SQL UPDATE employees SET salary = :salaries WHERE id = :ids; /* priklad pro DELETE */ EXEC SQL DELETE FROM employees WHERE id = :ids; /* obdobne pro SELECT pri znamem poctu vracenych radku */
●
počet změněných řádků při UPDATE a DELETE může být větší než velikost pole
Použití ve složitějších dotazech ●
●
●
počet zpracovaných záznamů po provedení SQL dotazu uchovává proměnná sqlca.sqlerrd[2] počet položek pole ke zpracování lze ovlivnit pomocí klauzule FOR při naplnění pole pomocí klauzule SELECT nebo FETCH je třeba použít pole indikátorových proměnných k testování navrácených hodnot
Použití sqlca.sqlerrd[2] /* pomocne promenne pro kontrolu cyklu */ int rows_this_time = ARRAY_SIZE; int rows_before = 0; int i; while(ARRAY_SIZE == rows_this_time) { EXEC SQL FETCH cur INTO :names:ind_names, :salaries:ind_salaries; /* update pomocnych promennych */ rows_this_time = sqlca.sqlerrd[2] rows_before; rows_before = sqlca.sqlerrd[2];
}
/* zpracovani dat nactenych do pole */ ...
Použití klauzule FOR ... VARCHAR names[ARRAY_SIZE][NAMELEN]; int salaries[ARRAY_SIZE]; EXEC SQL END DECLARE SECTION; /* pripojeni k databazi */ /* naplneni pole (filled_rows oznacuje pocet doopravdy naplnenych polozek */ EXEC SQL FOR :filled_rows INSERT INTO employees (name,salary) VALUES (:names,:salaries); /* bylo vlozeno prvnich filled_rows polozek pole */ ...
Omezení při použití polí ●
●
●
v dotazech s klauzulemi VALUES, SET, INTO nebo WHERE nelze zároveň použít pole a skalární proměnné při INSERTu nelze použít pole pointerů; v klauzuli VALUES musí být datové položky v dotazu na SELECT nelze použít pole v klauzuli WHERE (s výjimkou poddotazů)
Struktury v emb. SQL
●
●
● ●
●
v SQL dotazech lze používat jako proměnné celé struktury strukturu lze sestavit pouze z proměnných použitelných jako host variable (i pole) nelze používat vnořené struktury předem deklarovanou strukturu lze použít v klauzuli INTO při dotazech SELECT nebo FETCH a v sekci VALUES při dotazu INSERT nelze použít s PL/SQL
Deklarace Host Structures typedef struct empl{ int id; VARCHAR name[20]; int salary; } emp_record; EXEC SQL BEGIN DECLARE SECTION; emp_record employee; ... EXEC SQL END DECLARE SECTION;
●
na pořadí proměnných uvnitř struktury záleží v kontextu dotazu
Příklad použití struktur /* naplneni struktury employee */ ... EXEC SQL INSERT INTO employees (id,name,salary) VALUES(:employee); /* dotaz by neprosel pri nasledujici deklaraci: */ typedef struct { int id; int salary; VARCHAR name[20]; } emp_record;
●
proměnné musí "matchovat" na SQL dotaz
Multi-row & Multi-column operace ●
●
●
●
použití polí umožňuje pracovat s jedním sloupcem na mnoha řádcích použití struktur umožňuje práci s mnoha sloupci jednoho řádku tyto dva přístupy lze při dodržení jistých pravidel kombinovat Multi-row & Multi-column operace
Multioperace – dva přístupy ●
struktura obsahující pole
●
pole struktur
struct empl { int ids[ARRAY_SIZE]; VARCHAR names[ARRAY_SIZE][20]; int salaries[ARRAY_SIZE]; } multiempl;
struct empl { int id; VARCHAR name[20]; int salary; } employees[ARRAY_SIZE];
/* prislusna struktura indikatoru */ struct ind_empl { short ind_ids[ARRAY_SIZE]; short ind_names[ARRAY_SIZE]; short ind_sals[ARRAY_SIZE]; } ind_multiempl;
/* prislusne pole ind. struktur */ struct ind_empl { short ind_id; short ind_name; short ind_salary; } ind_employees[ARRAY_SIZE];
Pole jako součást struktury /* naplneni struktury multiempl */ EXEC SQL INSERT INTO employees (id, name, salary) VALUES (:multiempl INDICATOR :ind_multiempl);
●
● ●
řídí se stejnýmy pravidly jako práce s host arrays pouze "zabaleno" do struktury je vhodnější používat pole struktur
Deklarace Array of struct - omezení struct department { /* je nutne uvest structure tag */ int employees[20]; /* (1) – ERROR */ char empl_name[20][20]; /* (2) – ERROR */ struct salary{ /* (3) – ERROR */ int month; int hour; } salary; } deparments[10]; /* pole 10 oddeleni */
(1) s výjimkou typů char a VARCHAR nelze deklarovat pole uvnitř struktury (2) pole typů char a VARCHAR nesmí být vícedimenzionální (3) členem struktury nesmí být struktura
Použití Array of struct /* deklarace */ struct empl { int id; VARCHAR name[NAMELEN]; int salary; } empls[ARRAY_SIZE]; /* naplneni */ for(i=0; i < ARRAY_SIZE; ++i) { ... } /* pouziti v SQL dotazu */ EXEC SQL INSERT INTO employees (id, name, salary) VALUES(:empls);
Omezení Array of struct ● ●
●
●
nelze použít v klauzulích WHERE a FROM nelze použít v klauzuli SET uvnitř UPDATE dotazu pole struktur nejsou povoleny v blocích PL/SQL pole struktur nejsou povoleny v Oracle Dynamic SQL Method 4