Náš model aplikace je již dost rozsáhlý na to,
                  abychom nad jeho třídami mohli začít provádět
                  dotazování. Dnes si tedy ukážeme, jaké nám Caché
                  nabízí možnosti práce s dotazy na data, vracející
                  sady záznamů.
Jedním z častých dotazů v účetních aplikacích je
                  přehled zůstatků na účtech syntetické evidence, nebo
                  přehled pohybů na účtech – deník. Ukážeme si též, jak
                  lze v Caché tvořit uložené procedury a jak s nimi z
                  Javy pracovat (i když je to z pohledu objektového
                  programování samozřejmě krok zpátky, protože s Caché
                  umí Java spolupracovat objektově, ale někdy se
                  relační způsob může hodit.)
Samozřejmě, že dotazovat se na data v Caché můžeme
                  pomocí SQL i dynamicky, ale v takovém případě musí
                  server, pokud nemá již vygenerovaný runtime kód
                  našeho SQL dotazu nakešován, nejdříve příslušný kód
                  sestavit, což jej může zdržovat. Proto je vhodné,
                  alespoň u často používaných dotazů, tyto nadefinovat
                  jako součást definice třídy, a tedy se stanou částí
                  API aplikace.
Ukážeme si, jak sestavit sadu záznamů se zůstatky
                  na účtech syntetické evidence.
V Caché Studiu otevřeme třídu ucto.demo.Syntetika k editování. Pomocí
                  průvodce přidáním dotazu (menu Class -> Add ->
                  New Query) nadefinujeme seznam vstupních parametrů
                  dotazu (v našem případě žádné nebudou) a poté
                  vybereme, zda náš dotaz bude tvořen SQL příkazem nebo
                  kódem v některém ze skriptovacích jazyků Caché;
                  zvolíme SQL, sestavu nazveme OsnovaReport.
Definice dotazu bude vypadat takto:
Query OsnovaReport() As %SQLQuery(CONTAINID = 1)
{
SELECT %ID,cisloUctu,nazev,typ,aktualniZustatek as zustatek FROM ucto_demo.Syntetika
ORDER BY cisloUctu
}
Vidíte, že je to klasický SQL dotaz. Jediné co Vás
                  může zarazit, je parameter CONTAINID=1, ten říká, že
                  dotaz vrací identifikátor objektu (jako %ID) a pro
                  náš příklad není důležitý. Tento parametr je používán
                  jinými technologiemi. ID se však hodí pro následné
                  otevírání instancí objektů.
Po zkompilování třídy a vytvoření aktualizované
                  verze Java proxy třídy se dotaz stane součástí Java
                  projekce. Caché dotazy jsou vystaveny jako statické
                  metody vracející třídu CacheQuery.
                  Následující řádky ukazují jednoduchý kód volající
                  výše definovaný dotaz:
String url="jdbc:Cache://localhost:56773/" + namespace;
dbconnection = CacheDatabase.getDatabase (url, username, password);
System.out.println( "Spojeno." );
CacheQuery qry = Syntetika.query_OsnovaReport(dbconnection);
rs = qry.execute();
// hlavicka
String h = "";
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
if (i>1) h += ": ";
h += rs.getMetaData().getColumnName(i);
}
System.out.println(h);
while (rs.next()) {
/* vypiseme vsechny sloupce kazdeho nalezeneho radku */
String s = "";
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
if (s.length() > 0) {
s += ": ";
}
s += rs.getString( i );
}
System.out.println( s );
}
/* Close the ResultSet object */
rs.close();
V předminulém díle našeho seriálu jsme používali
                  metodu _open k otevírání instancí
                  Caché tříd. Tato metoda ovšem předpokládá, že známe
                  identifkátor instance. My jsme před chvíli viděli,
                  jak si identifikátory instancí objektů vrátit; pomocí
                  dotazu. Ovšem existuje i pohodlnější způsob než
                  samostatné volání dotazu a následné použití vráceného
                  ID pro použití v metodě _open, a to
                  metoda OpenByQuery, která kombinuje
                  oba kroky – nalezení ID a otevření objektu.
Ukázka otevření instance syntetického účtu s číslem
                  221:
Iterator it = Syntetika.openByQuery(dbconnection,"cisloUctu = ?",
new String[] {"221"});
// vime (cisloUctu je unikatni), ze pokud najdeme nejaka data, tak nanejvys jeden zaznam
if (it.hasNext()) {
Syntetika syn = (Syntetika)it.next();
System.out.println(syn.getcisloUctu() + " : " + syn.getnazev() + " : zustatek: " + syn.getaktualniZustatek());
}
Možná si ještě vybavíte, ze na počátku tohoto
                  seriálu, v jednom z dílů věnovaných technologii
                  Jalapeno, jsme tuto metodu používali také.
V tomto případě se sice SQL dotaz generuje
                  dynamicky, ale jelikož se jedná o prostý select z
                  jedné tabulky, režie na jeho sestavení je minimální.
Když už jsme u dotazování: vzhledem k tomu, že
                  Caché plně podporuje SQL, je možno použít standardní
                  SQL dotazy prostřednictvím JDBC rozhraní. Na tom není
                  nic objevného, takže si to ukazovat nebudeme. Ale
                  ukážeme si, jak lze v Caché označit metodu nebo dotaz
                  jako uloženou proceduru SQL pro volání (nejen) z Javy
                  nikoliv prostřednictvím objektové vazby, ale
                  prostřednictvím JDBC.
Udělat z vloženého dotazu nebo statické metody
                  třídy Caché uloženou proceduru, je velice jednoduché.
                  Stačí přidat k deklaraci metody či dotazu klíčové
                  slovo SQLProc a případně volitelný název uložené
                  procedury. (Stále pracujeme s definicí Caché třídy
                  ucto.demo.Syntetika)
Query Osnova() As %SQLQuery(CONTAINID = 1) [ SqlName = spOsnova, SqlProc ]
{
SELECT %ID,cisloUctu,nazev,typ,{FN CONCAT(aktualniZustatek,' Kč')} as zustatek FROM ucto_demo.Syntetika
ORDER BY cisloUctu
}
Uloženou proceduru pak spustíme jednoduše:
String url="jdbc:Cache://localhost:56773/" + namespace;
Class.forName ("com.intersys.jdbc.CacheDriver");
dbconnection = DriverManager.getConnection(url,username,password);
CallableStatement cs = dbconnection.prepareCall("{call ucto_demo.spOsnova()}");
ResultSet rs = cs.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
Příště se pustíme do projekcí Caché tříd do
                  Enterprise Java Beans.
