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; /* prislusna struktura indikatoru */ struct ind_empl { short ind_ids[array_size]; short ind_names[array_size]; short ind_sals[array_size]; } ind_multiempl; struct empl { int id; VARCHAR name[20]; int salary; } employees[array_size]; /* 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