
Nezobrazujúce sa záznamy databázy spojenej cez ADO v Delphi 2007
Mám databázu, ku ktorej som v Delphi 2007 pripojený cez ADO komponenty. V komponente DBGrid, ktorá má zobrazovať dáta z databázy v prehľadnej tabuľke, sa mi zobrazujú iba názvy stĺpcov tabuľky (načítali sa z databázy). No políčka, kde majú byť už konkrétne údaje záznamov, sú prázdne. Neviete mi niekto poradiť v čom je problém? Inak to isté robia aj ostatné komponenty, ktoré majú zobrazovať dáta z databázy.
Zistil som, že to bude asi databázou alebo tými ODBC drivermi. Pod WinXP sa v programe tie dáta nezobrazujú. No keď som program skúsil spustiť pod Win98SE, tak všetko v pohode išlo...
Máš pravdu, ty ODBC jsou v největším podezření, když to pod W98 pochoduje. Jedině se ještě podívat ještě na přístupová práva, WXP je mají víc ošetřeny.
Je to dosť zaujímavé. Znova som použil komponentu DBGrid, no dal som v nej zobraziť dáta z inej databázovej tabuľky. A zobrazujú sa aj pod WinXP aj pod Win98.
Pokud presne nepopises, co a jak delas, tezko se bude radit.
Všetky komponenty ADOConncetion, ADOQuery a DataSource mám na tom špeciálnom formulári (či ako to mám nazvať) s názvom DataModule1. Cez ADOConnection som pripojený na databázu Sybase SQL Anywhere 5.5 (beží to cez ODBC). V databáze je už množstvo údajov vo viacerých tabuľkách. Vo vlastnosti SQL komponentu ADOQuery1 je SQL príkaz s parametrom, ktorý načítava údaje z jedného záznamu tabuľky. ADOQuery1 je používaný komponentom DataSource1. Ten využíva viacero komponentov DBText, z ktorých každý má inú hodnotu DataField (čiže zobrazuje iný údaj). Dáta v týchto komponentoch DBText sa mi nezobrazujú pod WinXP (sú prázdne), no pod Win98SE je v nich z databázy načítané presne to, čo má byť. Tieto údaje sú zobrazené na formulári Unit2.
Ďalej komponent ADOQuery2 využíva len jednoduchý SQL príkaz na zobrazenie celej tabuľky (inej ako je tá, ktorú využíva ADOQuery1). ADOQuery2 je používaný komponentom DataSource2 a ten je využívaný komponentom DBGrid1. Všetky dáta v ňom sa mi zobrazujú aj pod WinXP, aj pod Win98SE. Toto všetko mám na formulári Unit3 (stále toho istého projektu/programu).
A nakoniec mám ADOQuery3, ktorý je využívaný komponentom DataSource3. Chcel by som vedieť ako dostať výsledok SQL príkazu, ktorý využíva ADOQuery3, do konkrétnej premennej, s ktorou môžem ďalej pracovať v zdrojovom kóde (v podmienkach a tak) hlavného formulára Unit1. Nenašiel som to ani v seriály o Delphi na Živě.cz, ani v knihe Mistroství v Delphi 6. Vedeli by ste mi poradiť?
Všetky formuláre majú samozrejme v položke USES pripojený DataModule1.
Můžeš sem, prosím, vložit ty příkazy SQL z těch ADOQyery? Obávám se, že do žádné proměnné nenacpeš výsledek nějakého SELCTu, musíš zpracovávat jeden řádek za druhým. Možná by kdybys někam uploadnul zdroják, abych se mohl podívat na to celé.
ADOQuery1:
ADOQuery2:
ADOQuery3:
Pod WinXP sa zobrazuje iba výsledok príkazu, ktorý používa ADOQuery2.
A v zdrojovom kóde môžu byť zaujímavé akurát nasledovné riadky (z hlavného formulára):
A jsi si jisty, ze ten format datumu je v poradku?
Neni problem v odlisnem formatu datumu a casu na Win98 a WinXP?
Proc nepouzijes dat do parametru ve formatu datumu a strkas to tam pres retezce?
Navic mi neni jasne, proc plnis parametry do Query 2 a 3, kdyz zadne parametry nemaji...
A ako tam mám dohodiť niečo vo formáte dátumu? Ten kus kódu, čo si napísal mi Delphi nezoberie. Vraj nepozná AsDateTime. Skúsil som niečo takéto, ale žiadna zmena nenastala:
Inak to Query 2 a 3 som už medzičasom zmenil a keď som to tu písal, akosi som na to zabudol. Teraz to u mňa vyzerá takto:
ADOQueryKasa1:
ADOQueryKasa2:
ADOQueryKasa3:
ADOQueryUroky1:
ADOQueryStartUp:
Omlouvam se, my to mame ADO komponenty upravene, aby se chovaly aspon trochu normalne.
Ve tvem pripade by to bylo:
Teraz to zas nepozná ftDate, ale nastavil som ho manuálne v ObjectInspectore a teraz to nejde ani pod Win98.
Ja jsem to zkousel na novem projektu. Na form jsem polozil TAdoQuery, nic jineho.
Pak to mas nejak rozbite
Ako mám dostať výsledok SQL príkazu do nejakej premennej, ktorú môžem ďalej využívať v podmienkach? Ak sa to nejde, tak sa dá aspoň dostať celý jeden záznam z databázy do jednoduchého poľa? Ktoré komponenty alebo čo iné mám použiť?
Vysledkem SQL prikazu je dataset (mnozina dat). Ty si musis precist, co potrebujes, napr:
promenna := ADOQuery.FieldByname('jmeno_pole').Value;
Na otestovanie som použil toto:
No akosi to nefunguje. Čo vlastne má byť tam, kde som dal datum?
Protoze datum je ze serveru vraceno v poli DateTime a Label.Caption je string, tak je treba pred prirazenim datum prevest na string:
Label1.Caption := DateToStr(DataModule1.ADOQueryKasa1.FieldByName('d atum').Value);
A keď to potrebujem použiť pri SQL príkaze SELECT max(datum) FROM kasa? Píše mi, že "Field" datum neexistuje. Je to asi preto, že to vráti iba jednu hodnotu (najväčší dátum). No kde to potom nájdem?
SELECT max(datum) as Datum FROM kasa
A najednou field Datum existuje...
Teraz mi zas vypisuje 'Could not convert variant of type (Null) into type (Double)'. Možno to súvisí s tým, že pod WinXP sa mi nezobrazujú tie záznamy a tak sa to tvári ako dátový typ Null. Hľadal som na Googli, ale je tam toho strašne málo a píšu o tom len Španieli a Číňania.
EDIT: Zistil som, že pod Win98 to ide normálne. Žiadne chybové hlášky a v komponente Label1 sa zobrazí ten najväčší dátum.
S datumem jsou vždy problémy. Zpracování datumu je nejlepší vždy nechat na systému přes parametry dotazu SQL. Hodnota NULL není v datumovém poli příliš vhodná, ošetřit za pomocí IS NULL. IMHO nebude záležet na Win98/XP - i když drivery ODBC můžou mít své chyby. Spíš zkontroluj, jestli nemáš různé národní nastavení zobrazení datumu. Na tom tady taky hodně záleží.
No už ma to fakt nebaví. Neviete mi poradiť akú databázu použiť, aby s ňou Delphi 2007 vedelo bezproblémovo pracovať (cez niečo viac zdokumentované ako je ADO), aby išla aj pod Win98 a podporovala uložené procedúry?
ADO mas zdokumentovane dokonale na MSDN. Tvuj problem bude ve formatu datumu - protoze jej tam posles v blbem formatu, server ti nic nevrati. Kdyz uz to prevadis na retezec, zkus aspon normalizovany format 'yyyymmdd' - tak ja to vidis, bez pomlcek
Ja tam už dávno dohadzujem čisto len Date. Pod Win98 to ide, no pod WinXP nie. Preto si myslím, že chyba nebude v mojom zdrojáku, ale v tom ako WinXP (konkrétne tie ODBC drivery) pracuje s tou starou databázou (nevie v nej rozoznať dátové typy alebo s nimi pracovať a...).
A na tie anglické návody na MSDN fakt nemám čas. Keď niečo čítam v slovenčine (poprípade češtine), tak si to aj zapamätám. Ale v angličtine viem akurát o čom je veta alebo odstavec, ktorý čítam. Niežeby som nevedel po anglicky, ale po prečítaní z toho väčšinou nič nemám. Hlavne ak by som teraz k tomu ADO musel čítať brutálne veľa o všetkých komponentoch, ich vlastnostiach a použití.
Proste stále mi Delphi vyhodí nejakú chybu. A pri každej skúšať či to náhodou nejde pod Win98, hľadať každú jednu na Googli, či písať do fóra, tak to ten program nezrobím ani za 10 rokov.
Rozmýšľal som už o C++, ku ktorému je toho viac v slovenčine/češtine. Lenže Borland C++ Builder sa mi akosi nedarí nainštalovať. A v Dev-C++, ktorý mi poradil jeden kamarát a ktorý som nainštaloval len pred chvíľou, sa všetko píše len v zdrojovom kóde (žiaden formulár nevidno počas tvorby programu/pred skompilovaním), takže by som sa musel od základov učiť C++. Aj keď síce už niečo viem, pretože doteraz som sa venoval len tvorbe webových aplikácii v PHP, ktoré má syntax práve z C++.
No tak už neviem. Možno to nechám tak a prídem o pekný zisk...
Obávám se, že ti C++ nepomůže. Není to syntaxí Delphi či C++ ale syntaxí SQL a jeho zobrazení datumu. Nemáš náhodou nastaven jiný národní formát datumu ve Win 98 a v XP? Nemáš jedny win české a jedny anglické (US)? Problém též na 99% nebude v ADO ani ODBC, ale v SQL. Ve Win 98 a XP se připojuješ ke stejnému serveru, nebo máš na ladění v obojím nějakou lokální instalaci? Je v obou Win stejná konfigurace databázového serveru? Jaký vůbec používáš databázový stroj (omlouvám se, jestli jsem to v tomto threadu přehlédl)?
Neviem aký formát dátumu myslíš. Veď pod oboma Windowsami nie sú žiadne podrobnejšie nastavenia dátumu/času.
Na obidvoch PC (s WinXP aj s Win98) je databáza nastavená v Microsoft ODBC Administrator ako System DSN. Konfigurácia je na oboch PC úplne rovnaká. Databáza je Sybase SQL Anywhere 5.5 a už dlhé roky s ňou pod Win98 (a asi aj pod Win95) pracuje stará verzia programu, ktorý mám teraz odznova urobiť.
Teraz mi zas vypisuje chybu 'Cannot convert 1857 to a date' v tomto riadku:
Ten je súčasťou nasledujúcej časti zdrojového kódu:
To je jak u blbejch. Kdyz ti poradim, abys datum daval ve formau yyyymmdd, ty mi odpovis, ze uz to davno davas jako date a pak uvedes ukazku kodu, kde mas nekolikrat:
Tobe jina databaze nepomuze. Bohuzel jedine, co ti pomuze je rozumet tomu, co pises.
A muzes se samozrejme spolehat na pirazovani variantu a jejich "nejakou" konverzi, ale nemas zadnou kontrolu nad typy.
Pred par prispevky jsem ti psal, jak nastavit typ parametru. Zkus si to precist.
Sorry, som myslel, že v tomto prípade to nič neovplyvní. Inak díky za upozornenie, dal som tam yyyymmdd a už nevypisuje tú chybu. Teraz to zas hlási 'CommandText does not return a result set.'.
Inak tá procedúra v databáze, ktorá je aj v tom kúsku zdrojáku, pridáva do databázy nový záznam. A ten záznam sa už pod WinXP zobrazil, až na tie dve položky Stav a Pohladavky, ktoré tá procedúra prijíma ako parametre. Asi som tam dal zlý dátový typ. Ale čo tam mám dať, aby to bolo kompatibilné, keď v databáze sú dátové typy decimal (10,0) a decimal (10,2)? Ako DataType oboch parametrov tam databáza dohodí ftBCD, no čo mám dať ako Value.Type?
A ty se divis, proc ti to tu chybu pise?
Opakuji. Sam nevis co pises.
Doporucuji se zamerit na DataModule1.ADOStoredProc.ExecProc;
V helpu si najdi, co udela ExecProc a co tam musis misto toho dat, aby ti to vratilo resultset.
No, to máš pravdu, že neviem, čo píšem do zdrojáku, lebo to nemám z kade vedieť. Robím to metódou pokus-omyl. Myslím tie veci s ADO komponetami. O ostatných sa aj niečo píše na Živě.cz či v knihe Mistroství v Delphi 6.
A teraz neviem, čo si myslel. To, že tam má byť namiesto DataModule1.ADOStoredProc.ExecProc riadok DataModule1.ADOStoredProc.Open, alebo niečo iné? Fakt neviem čo mi to robí, pretože to vždy zmaže celú databázu a vloží tam záznam s dnešným dátum a jeden s dátumom 30.12.1899.
Pokud to maji byt castky, tak v databazi pouzij typ Money nebo Curency. To je typ s pevnym poctem desetinnych mist.
Pokud nemuzes menit strukturu, pak si musis nastavit typ dat parametru jako dtCurrency
No, pekne. Teraz mi blbne už aj samotné Delphi. Keď kliknem na ENTER, tak mi nevytvorí nový riadok, ale iba kurzor skočí o riadok nižšie, ako keby som stlačil šípku dolu. A zas keď kliknem na SPACE, tak mi nezrobí medzeru, ale sa len kurzor posunie o jeden znak doprava, ako keby som stlačil šípku doprava. Inak všetko ostatné funguje. Myslím písanie všetkých znakov a dokonca aj ich mazanie (BACKSPACE).
Nemas vypnuty Insert?
Díky, ja by som na to asi nikdy neprišiel.
Inak ten problém s nezobrazovaním dát z databázy pod WinXP som už vyriešil, no radšej tu nepíšem čím to bolo, lebo by ste ma asi zabili. Proste bolo to spôsobené len mojou hlúposťou alebo skôr nevšímavosťou (mimo Delphi).
A ešte mám jednu otázku: Ako môžem zistiť, či databázová tabuľka obsahuje nejaké záznamy alebo je prázdna? Myslím cez Delphi, keď to chcem použiť v podmienke: Ak je tabuľka prázdna, vloží záznam s určitými hodnotami a keď už nejaký záznam obsahuje, spustí procedúru z databázy (čo sa mi mimochodom už tiež podarilo urobiť).
Provedes dotaz:
select count(*) as Pocet from Tabulka
Vrati se ti pocet zaznamu v tabulce
Díky, ale nevracia to náhodou pri prázdnej tabuľke NULL?
Klídek, nikdo tě vraždit nebude, možná by to bylo zajímavé čím to bylo, třeba pro někoho jiného, aby si také tak nenaběhl. Hlavně, že ti to běží. Držím ti palce v dalším programování.
Ako som už vyššie písal, prerábam jeden starý program. Mám ho nainštalovaný v adresári Program Files, kde je aj databáza, ktorá beží cez ODBC. Všetky databázové tabuľky boli prázdne a preto sa mi v novom programe, ktorý robím, nič nezobrazovalo. Lenže ja som celý čas cez jedného SQL klienta pristupoval k druhej (rovnakej) databáze, ktorá bola v adresári s tým klientom a ktorá už obsahovala nejaké záznamy. Vtedy som si myslel, že stále pomocou môjho programu aj toho SQL klienta pristupujem k tej istej databáze. Prišiel som na to až vtedy, keď som mal spustený ten program, ktorý robím, a v tom istom čase som spustil toho SQL klienta. Ten SQL klient sa automaticky pripojil k tej dobrej databáze (čo som vtedy ešte nevedel), zrazu som sa čudoval, prečo sú databázové tabuľky prázdne, a potom mi to došlo.
Nedá sa nejak urobiť aby sa po stlačení ENTERu automaticky stlačilo konkrétne tlačidlo na formulári, v momente keď je kurzor v komponente Edit (teda keď niečo píšem)? Viem síce urobiť, aby sa po stlačení ENTERu niečo vykonalo, ale vždy sa mi pri tom ozve ten zvuk Windowsu, ktorý signalizuje, že sa niečo nedá (teda neviem to inak opísať).
A ešte nedajú sa nejak uvoľňovať zavreté formuláre z pamäti? Sledujem totiž, že stále keď otvorím formulár, program uloží do pamäte ďalších pár kB. Dokonca si jednotlivé formuláre stále držia svoje premenné po zavretí a opätovnom otvorení. Formuláre otváram príkazom ShowModal a zatváram príkazom Close. Keď použijem príkaz Free, tak konkrétny formulár už počas toho istého chodu programu neotvorím. To už sú princípy OOP, ktorým som sa zatiaľ nezaoberal (viem, čudné, keď programujem v Object Pascale
). Ale neviete mi aspoň poradiť ako uvoľniť premenné z pamäti pri zatváraní formulára?
Som síce už riadne OT, ale nechcem zbytočne zakladať novú tému.