Delphi - BDE - TQuery - tabuľka v pamäti
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, DBTables;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Query1: TQuery;
end;
var
Form1: TForm1;
Field1: TFloatField;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Query1 := TQuery.Create(Self);
Field1 := TFloatField.Create(nil);
Field1.FieldName := 'Cislo';
// Field1.Size := 5;
Field1.DisplayWidth := 5;
Field1.Precision := 2;
Query1.Fields.Add(Field1);
Query1.Active := True;
DataSource1.DataSet := Query1;
try
Query1.Append;
Query1.Fields[0].AsFloat := 10;
Query1.Post;
finally
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Query1.Free;
end;
end.
Čo robím zle? Ak povolím riadok Field1.Size, tak dostanem chybu, že je to chybná dĺžka, ak to nepovolím, tak pri Active := True dostanem "No SQL statement available". Keďže je tabuľka vytváraná v pamäti, tak jej fyzické meno neexistuje. Zrejme je chyba niekde v tom. Tiež by ma zaujímalo, čo s tou dĺžkou.
A co s tim Fieldem chces vlastne delat ? TField se definuje nad existujici tabulkou. Neslouzi k definici struktury. Pokud chces definovat strukturu, podivej se na property tabulky FieldDefs
V helpe som našiel toto:
Problém je v tom, že mi to neprejde vetvou then. Na začiatku mám toto:
Table.Exists nekontroluje existenci objektu (to tve vytvoreni), ale existenci tabulky na disku. Musel bys priradit TableName, pak muzes kontrolovat Table.Exists
Veď je tu riadok:
TableName := 'CustInfo';
Pises, ze ti to neprojde pres IF - THEN
Co ti to napise ? Mas nainstalovane vzorove databaze ? Protoze to demo se pripojuje na dema, ktera se instaluji s Delphi.
Určite tie databázy mám. Nainštaloval som všetko okrem toho, čo sa pýta inštalovať po nainštalovaní Delphi. Ako sa to len volalo? Malo to myslím niečo spoločné s Javou, ale neviem si spomenúť na názov. Interbase som nainštaloval tiež. Tie databázy neviem v akom adresári majú byť a neviem ich nájsť.
Ale v príklade je písané, že to vytvorí databázu iba v prípade, že neexistuje na disku, takže aký to má súvis s demo databázami?
Edit: Nenapíše to nič, len to prejde na koniec vetvy then. Podmienka je totiž splnená.
Bodejd by nebyla splnena, kdyz ta tabulka existuje
Zkousel jsi zmenit jmeno tabulky ?
Databazi nech prazdnou a do TableName predej jmeno tabulky vcetne cesty
Áno, už som to zistil. Pri prvom prechode sa nič nestalo, lebo som nenastavil Active na True a nemal som nadefinovaný DataSet v DataSource. TAkže DBGrid ostal prázdny. Teraz som si uvedomil, že tú tabuľku to niekde muselo vytvoriť, tak som na vašu radu zmenil meno. Vetva then prebehla a potom som si uvedomil to Active a DataSet, tak som zmenil meno znova a pridal som priradenia (je to totiž vo vetve then (ale to len teraz na skúšku)). Funguje to a mám, čo som potreboval. Vyriešené, ďakujem za pomoc.
Teraz ešte taký detail: Ak chcem vytvoriť TQuery, tak to musím urobiť cez TTable a ten následne otvoriť v TQuery? Alebo sa dá nejako vytvoriť priamo TQuery?
Query se pouziva na vyber dat. Takze se nbevytvari zadne struktury, ale pomoci SQL prikazu se vybiraji data z existujicich tabulek:
Vysledkem je tabulka se 3 poli (Cislo, Jmeno, Plat) a jejich typ a velikost je dana poli v puvodnich tabulkach
Pokud chces memory tabulku, jdes na to uplne spatne. Query slouzi pro vyber dat z existujici databaze. Ty potrebujes napr. ClientDataset z Delphi nebo stahnout kbMemTable, tusim, ze i v rx library je jedna memory tabulka.
Nie je to celkom tak. Ja chcem toto:
A neni jednodussi jit cestou:
Pokud neexistuje tabulka, zkopiruji ji z adresare, kde mam vychozi prazdne tabulky ?
Už som nad tým uvažoval, ale sa mi to riešenie veľmi nepáči. Zdá sa mi to také neprogramátorské. Chcel by som sa naučiť vytvoriť to programovo.
Jestliže chceš vytvořit programově tabulku, když není na disku přítomna, tak na to musíš takto:
Na form nebo TDataModule prskni TTable. V objektu TTable dvojklikem otevři Field editor a nadefinuj všechny potřebné fieldy (pravá packa myši v prostoru Field Editoru, vybrat Add Fields.. a dál už uvidíš). Dál dvojklikem na IndexDefs (v Object Inspectoru) obdobným způsobem vytvoř potřebné indexy. Nakonec nastav StoreDefs na TRUE a vhodně TableName a DatabaseName. V programu udělej něco podobného:
Ďakujem, ale už mi funguje čisto programový spôsob. Predpokladám, že toto je vlastne to isté, ale cez vizuál. Veď časom uvidím, čo mi bude lepšie, ale asi prejdem na vizuál. Ani ma nenapadlo, že aj tak to ide.
Program je kratší a přehlednější, když to navrhneš visuálně. Na rychlost a nárok procesoru to bude asi 1:1. Při visuálním návrhu se většina práce udělá "za oponou" - z resources se to přežvejká do naprosto stejné podoby, kterou ty naprogramuješ růčo. Jako tréning programování je to lepší udělat čistě programově, pro rutinní použití je rychlejší a spolehlivější visuální návrh - od toho byl vymyšlen .
A ešte odpoveď na tú otázku naspodu príspevku?
http://pc.poradna.net/question/view/47861-delphi-bd e-tquery-tabulka-v-pamati#re-47941
TQuery není tabulka, je to SQL dotaz. TQuery vůbec nemusí mít definované fieldy (ostatně TTable také ne, jestliže slouží jen ke zpracování existující tabulky a neslouží k vytvoření nové). Výsledkem TQuery je tabulka, která vznikne dotazem SQL (SELECT f1, f2,... from tabulka where....). Výsledná tabulka je jednosměrná (lze se pohybovat jen vpřed) má-li TQuery.UniDirectional := TRUE a lze v ní dělat změny je-li TQuery.RequestLive := TRUE. Výsledkem TQuery může být i výběr z několika tabulek a změny se promítnou zpět do příslušných tabulek (podmínkou je, aby měly primární klíče). Přístup k polím může být třeba před Query1.FieldByName ('Jmeno').AsString.
No, to mi ako odpoveď stačí. S TQuery sa dá pracovať rovnako ako s TTable, ak už súbor existuje. Takže to urobím tak, že vytvorím TTable, zavriem, otvorím TQuery a môžem s tým veselo pracovať.
Jestli nepoužiješ SQL dotaz (SELECT), pak TQuery použít nemůžeš (teda můžeš: SELECT * FROM tabulka - ale je to zbytečné drbání přes cizí hlavu). Pakli budeš číst tabulku sekvenčně a všechny věty, maximálně seřazenou nějakým indexem, je lépe použít rovnou TTable která míří rvonou do souboru. TQuery nejdřív přenese věty podle SQL dotazu do pracovního souboru na lokálním počítači (v BDE Session.PrivateDir), tam se to zpracuje a případné změny pak zase vrací do tabulky. TTable pracuje se souborem přímo a rychleji (když se nečiní SQL výběr z jedné nebo vícero tabulek). Můžeš klidně vytvořit tabulku přes TTable a dál s ní pracovat přes totéž TTable.
//Edit: I když na druhou stranu by se programátor měl učit pracovat s tabulkama jen přes SQL příkazy...
//Edit2: A když už jsme u toho, lze tabulku i v Delphi+BDE založit příkazem SQL (pástnuto z helpu BDE) :
Mne sa na SQL páči to, že ak "indexujem" cez SQL, tak nemám plno zbytočných súborov. Okrem toho som si užil "srandy" s problémovými indexovými súbormi, ktoré som musel vytvárať nanovo. Tých tabuliek bude dosť a ešte pre každú index, tak to je na mňa veľa. Je teda ozaj lepšie používať TTable? Počítam rádovo tisíce záznamov v hlavnej databázi, ktorá bude stále narastať a vytvárať sa bude z iných.
Indexy mají hodně do sebe. Když použiješ indexy na pole, podle kterých přes SQL vybíráš, tak je SQL využije a jede velice podstatně rychleji. Jinak si SQL server (záleží na konkrétní implementaci - BDE, MSSQL, MYSQL, ...) vytvoří tytéž indexy přechodně, což při častých dotazech zdržuje, než když už jsou hotovy. Takže indexové soubory nejsou nikdy "zbytečné". Shrnul bych to asi takto: Když pracuješ s jednou tabulkou bez vazeb na další (bez SELECT ... JOIN) a zpracováváš všechny věty (bez SELECT ... WHERE/HAVING), je rychlejší použít tabulku (i pro jiné SQL servery - třeba MSSQL, MySQL - zde použiješ TAdoTable). TQuery (obecně tedy dotaz SQL - BTW SQL dotaz jde použít přímo přes TDatabase bez TQuery) použij, jestliže spojuješ vícero tabulek do sebe a vybíráš jen některé záznamy podmínkama WHERE popřípadně když vysčítáváš tabulku (SELECT...GROUP). Ufff.
Nedokážem pridať položku (stĺpec), pretože mi to stále dokola vypisuje toto:
Samozrejme, že tabuľka neexistuje. Veď preto ju idem vytvoriť, aby existovala. Čo s tým teraz?
Omlouvám se, vyber volbu "New field" a nadegfinuj sloupec tabulky. Opakováním "New field" nadefinuj všechny sloupce. Volba "Add field" a "Add all fields" naimportuje definici sloupců z již existující tabulky.
Práveže nie, mal som kliknúť na New Field, teraz som zistil, ale už mi to nedovolilo editovať príspevok. A klikol som naozaj na Add Fields.
Edit: Ale ďakujem za rýchlu reakciu.
Jsi sakra rychlej. Než jsem tu blbost po sobě přečetl, tak jsi jí viděl i ty.
Nie sme každý neomylný. Stane sa kaaždému. Len najhoršie na tom je, že sa to občas stáva v situáciách, keď sa to stať nesmie.
Díky.
Takže všetko som urobil. Aj indexy pekne vo vizuále vytváram, ale ako zadám do položky TIndexDef.Fields vo vizuále dve položky naraz? Napríklad MENO, SIET? Ide o to, že neviem akým znakom oddeliť tie dve položky v reťazci.
Do pole Fields oddělíš jména sloupců středníkem. Například: "Prijmeni;Jmeno". Pozor, v BDE je drobná chyba: Ve všech indexech (mimo primárního) zaškrtní "ixCaseInsensitive" - i když se jedná třeba o číslo. Jinak to může při vytváření tabulky nebo při obnově indexů řvát neprávem chyby.
Ej a tu je problém. Ja potrebujem, aby to nemalo vlastnosť "case sensitive".
No však, [ixCaseInsensitive] znamená: ne "case sensitive".
To in mi trošku uniklo.
A ešte otázka: TQuery má vlastne všetky vymoženosti ako aj TTable. Vo vizuále mu môžem nahádzať položky, indexy už nie. Dá sa takto vytvoriť aj databáza v TQuery? Alebo len tým SQL príkazom spomenutým nižšie (čiže vo vizuále si môžem nahadzovať čo chcem a podstatný je SQL príkaz)?
TQuery má téměř všechny vymoženosti, protože stojí na třídě TDBDataSet a tím všechny podobnosti končí. TTable je prostě přímé spojení s tabulkou, TQuery je výsledek dotazu SELECT (což je v podstatě virtuální tabulka). Přes SQL lze vytvořit tabulku, ale musíš použít buď metodu Execute objektu TDatabase - takto Database1.execute (const SQL: String; Params: TParams = nil; Cache: Boolean = False; Cursor: phDBICur = nil): Integer; - význam parametrů viz help. Nebo rychleší je použít přímo API funkce BDE - jestli máš můj modul pro práci s BDE Rce_BDE (nabízel jsem ho kdysi ke stažení), je to metoda ExecSQL. Může vypadat například takto:
//Edit Toto je cesta pro příkazy SQL kategorie DDE. Pro příkazy SQL kategorie DML existuje ještě objekt TUpdateSQL, kterým jdou vyslat příkazy DELTE, UPDATE a INSERT (přes výše uvedenou mojí rutinu jdou tyto příkazy vyslat také).
DDE = data definition language = prostředky na definici dat například příkazy CREATE TABLE (vytvoření tabulky), ALTER TABLE (změny definice tabulky), DROP TABLE (smazání tabulky), CREATE INDEX, DROP INDEX.
DML = Data Manipulation Language = manipulace s daty - příkazy SELECT, DELETE (odstranění vět), INSERT (vložení vět z příkazu nebo jiné tabulky), UPDATE (změna položek tabulky).
To je teraz na mňa trochu moc. Ten súbor mám, pozriem si to.
Všetko mi funguje, až na jeden nepochopiteľný detail. Na začiatku sa mi vytvorí tabuľka, ktorá na disku nie je a po ukončený programu ju na disku nájdem aj s obsahom. Po opätovnom spustení programu mi to prejde vetvou then a tabuľka je čistá:
DatabaseName som doteraz nastavené nemal, tak som to rýchlo nastavil na 'DBDEMOS', ale správa sa to rovnako.
Podivné. Já to dělám taky tak:
Zistil som, že vlastnosť Exist má stále hodnotu False.
Ak sa nebojíš mojich kódov, tak ti to asi pošlem. Ja som už nervy s tým stratil. Už som všetky vlastnosti prešiel aj 3x a nič.
Odoslané na: info@arkotechnik.cz
Tak jsem ti před chvílí majlem odpověděl.
Nejako ten mail mešká. Ale veď sa dočkám. Ďakujem.
Á doprde**.. Já si to z práce forwardoval domů a reply se poslalo zpátky do práce . Už jsem to napravil. Příště mi posílej majl na rce@... (dál je to stejné jako jsi posílal). To mi přijde jak domů, tak i do práce a jen mě soukromě.
Síce meškal, ale práve dorazil, idem čítať, ešte raz ďakujem.
Nemáš za co.
Ďakujem. Pomohlo. A ja si môžem lámať hlavu. Môžem poprosiť o vysvetlenie významu DatabaseName? V helpe je napísané niečo v zmysle, že to určuje alias databázy alebo proste názov s akým vystupuje databáza, ale nerozumiem, čo to má spoločné s cestou.
Je to název databáze. V BDE je databáze řešena jako adresář, tudíž zde jde napsat cesta k datům. Je tu možno také uvést Alias databáze (zástupné jméno, zástupce pro označení toho adresáře), které je nadefinováno v BDE administrátoru (nebo API funkcema BDE - viz můj modul Rce_BDE).
Ďakujem, teraz už toto multirozvláknené vlákno hádam môžem uzavrieť.
Dobrá. Kdyžtak založ čerstvé vlákno na nový dotaz.