14. API BDE I

BDE (Borland Database Engine) je 32-bitové jádro modulu přístupu k databázi pro prostředky firmy Borland. BDE nabízí dostatečnou množinu služeb pro vývojáře databázových aplikací typu klient/server.
BDE má architekturu založenou na ovladačích. Každý databázový formát nebo datový zdroj obvykle vyžaduje samostatný ovladač BDE. Daný ovladač může podporovat uzavřenou rodinu datových zdrojů. Např. ovladač dBASE podporuje dBASE III, dBASE IV a novější a FoxPro verze 2.0, 2.5 a 2.6.
BDE je navržen objektově orientovaně, což usnadňuje jeho rozšiřování a přizpůsobování. K rozšíření BDE na přístup k dalšímu databázovému systému, jednoduše instalujeme příslušný ovladač BDE nebo ovladač ODBC pro tento databázový systém.
V prostředí klient/server, aplikační a vývojové nástroje sídlí na klientském počítači, zatímco datové zdroje jsou umístěny na databázovém serveru. BDE poskytuje transparentní přístup k databázovým serverům a lokálním databázím.

Funkce API BDE

BDE obsahuje API pro přímý přístup ke své funkčnosti. API obsahuje množinu funkcí, které mohou být volány z libovolného programovacího jazyka umožňujícího volání DLL Windows. Funkce BDE jsou optimalizovány pro volání z C nebo C++.
Dva různé typy databázových systémů tradičně podporují různý přístup k datům: Funkce BDE jednotně přistupují k oběma těmto typům databázových systémů s konzistentním na kurzoru založeném API. Prostřednictvím ovladačů, BDE dává vývojářům aplikací přístup k unikátním službám každého databázového systému, jako jsou datové typy a speciálnímu zpracování SQL databází.
Pro všechny podporované databáze pro které je dostupný přirozený ovladač BDE nebo ovladač ODBC, volání funkcí API BDE slouží k následujícím účelům:

Objekty BDE

BDE je při návrhu objektově orientované. Za běhu aplikace, vývojář aplikace spolupracuje s BDE vytvářením různých objektů BDE. Tyto běhové objekty jsou pak použity k manipulaci s databázovými entitami jako jsou tabulky a dotazy. Programování pro BDE vyžaduje interakce s objekty BDE.
Každý typ objektu BDE je definován množinou vlastností. Hodnoty jsou přiřazeny k vlastnostem při vytvoření objektu. Např. jméno tabulky CUSTOMER je hodnota přiřazená k vlastnosti jména tabulky objektu kurzoru, když tabulka CUSTOMER je otevřena.
Rozhraní API BDE poskytuje množinu funkcí, které vývojář aplikace může použít k získání existujících hodnot vlastností a k nastavování těchto hodnot.
Jeden objekt system řídí zdroje společné pro všechny aplikace spuštěné na stejném počítači. Objekt system je automaticky vytvořen API BDE při první inicializaci klienta. V tomto okamžiku všechna konfigurační nastavení jako např. maximum paměti povolené pro vyrovnávací paměti, jsou přečtena z Registrů Windows.
Nový objekt client je vytvořen, když aplikace volá inicializační funkci BDE. Toto první volání DbiInit je nutno provést dříve než je možno volat jiné funkce BDE. Objekt client je udržován automaticky BDE a existuje hlavně jako kontext pro všechny systémové zdroje použité BDE pro každého klienta. Objekt client má také vlastnosti, které mohou být nastaveny.
Ovladače databáze jsou vlastněny klientem nebo systémem; po zavedení ovladače, všechny ostatní klienti registrované BDE, k němu mají přístup.
Aplikace může udržovat jedno nebo více sezení. Sezení izoluje databázové přístupové operace bez nutnosti spuštění jiné instance aplikace. Když je aplikace inicializována, pak je vytvořeno automaticky implicitní sezení. Objekt session je kontejner pro všechny ostatní běhové objekty BDE, které mohou být vytvářeny, tj. Databáze, Kurzory a Příkazy dotazu.
Pokud náš přístupový objekt je vytvořen v jiném sezení, pak současné sezení bude změněno na sezení ve kterém objekt byl vytvořen. Sezení je také vlastník všech tabulek a zámků záznamů získaných všemi objekty v sezení. To znamená, že tabulky nebo uzamčené záznamy získané pomocí jednoho kurzoru v sezení jsou vlastněny všemi kurzory v sezení, které jsou otevřeny na stejné tabulce. Další sezení mohou být vytvořena k umožnění jiného uzamykacího kontextu.
Další vlastností sezení je privátní adresář, kde BDE umisťuje všechny dočasné tabulky založené na souborech vytvořené sezením. Dále sezení vlastní dvě vlastnosti specifické pro ovladač Paradoxu: heslo (pro umožnění přístupu k tabulkám chráněným heslem) a síťový řídící adresář, kde je umístěn soubor PDOXUSRS.NET.
Každý databázový ovladač je zaveden systémem, když aplikace poprvé požaduje službu z tohoto ovladače. V tento okamžik, všechny konfigurační nastavení nalezené v Registrech Windows nebo konfiguračním souboru BDE týkající se tohoto ovladače jsou použity k jeho inicializaci. Ovladače jsou vlastněny klientem nebo systémem; jednou zavedený ovladač mohou používat všechny klienti registrované BDE. Vývojář aplikace se může také informovat o možnostech ovladače, jako je schopnost ovladače podporovat transakce.
Standardní ovladače pro Paradox, dBASE, Access, FoxPro a textové databáze jsou dodávány s BDE. Pro databázové systémy SQL jako je Informix, DB2, InterBase, Oracle a Sybase jsou dostupné samostatné přirozené ovladače BDE SQL. Libovolné ovladače ODBC mohou být použity s BDE, protože BDE má konektivitu s ODBC. Funkce BDE jako DbiAddAlias a DbiOpenDatabase automaticky přidávají ovladače ODBC a datové zdroje jako přezdívky BDE na aktivní sezení pokud nejsou právě uloženy v konfiguračním souboru. BDE také podporuje ovladače ODBC 3.
Databáze je organizovaná kolekce svázaných tabulek. Pro přístup k datům v tabulce, sezení musí nejprve získat přístup do databáze voláním DbiOpenDatabase, které vrací madlo databáze.
Souborově založené databáze, jako je Paradox, dBASE, FoxPro, Access a text, BDE klasifikuje jako "standardní" databáze. Soubory ve standardních databázích jsou normálně seskupovány do adresářů přiřazených ke standardním databázím, i když aplikace může specifikovat úplnou specifikaci souboru a zpřístupnit libovolné soubory a to jak lokální nebo umístěné na síti.
SQL databáze obvykle sídlí na serveru. Klientské aplikace se musí nejprve přihlásit a zřídit připojení na databázový server. To vyžaduje předání příslušného jména uživatele a hesla. Když voláme DbiOpenDatabase, pak BDE se připojuje k serveru a zřizuje připojení stejně jako pro standardní databáze.
Přezdívky jsou zkrácená jména odkazů na databáze. Databázové odkazy v aplikaci mohou používat jména přezdívek, což dělá aplikace přenositelnými. Definici přezdívky můžeme změnit kdykoliv pomocí Administrátora BDE. Všechny odkazy na přezdívky v aplikaci automaticky ukazují na novou definici přezdívky.
Pro standardní databáze, přezdívka je jméno přiřazené jako zkratka k adresáři obsahujícím soubory, ke kterým chceme přistupovat. Když otevřeme databázi s přezdívkou, pak tabulka v adresáři může být otevřena uvedením pouze jména tabulky bez nutnosti poskytnutí úplné cesty.
Pro SQL databáze musí být pro přezdívku definovány vlastnosti. Tyto vlastnosti jsou značně závislé na ovladači SQL. Vlastnosti přezdívky zahrnují: jméno uživatele, jméno serveru, režim otevření, implicitní režim dotazu, jazykový ovladač apod. Po zřízení přezdívky pro SQL databázi, ji klientská aplikace používá stejným způsobem jako používá přezdívku pro standardní databáze.
BDE poskytuje přístup k tabulkám a výsledkům dotazů prostřednictvím kurzorů. Kurzor umožňuje adresovat záznam v kolekci záznamů. Všechny operace manipulace dat (vkládání, rušení, aktualizace) a také pohyb kurzoru po tabulce (někdy nazývaný jako navigace) jsou prováděny s kurzory. Když aplikace otevře tabulku voláním DbiOpenTable nebo provede dotaz, pak je vráceno madlo kurzoru. Po návratu madla kurzoru, jej můžeme použít k získání dat uložených v tabulce stejně jako informací o tabulce. Můžeme také získat nebo nastavit vlastnosti tohoto kurzoru. Aplikace může kdykoliv uzavřít kurzor voláním DbiCloseCursor. Když je kurzor uzavřen, pak madlo kurzoru se stane neplatným. Na jedné tabulce může být vytvořeno více kurzorů.
Pro přístup k datům v tabulce, aplikace otevře tabulku a získá madlo kurzoru. Tabulka může být otevřena výlučně nebo sdíleně. Překladový režim může být specifikován jako xltNONE nebo xltFIELD. Pokud je specifikováno xltNONE, pak data z tabulky jsou vracena jako nepřeložený fyzický typ (přirozené datové typy jak jsou uloženy datovým zdrojem). Když je specifikováno xltFIELD, pak data jsou přeložena na obecné logické typy BDE. Logické typy jsou kompatibilní s datovými typy jazyka C.
Implicitně, záznamy vracené kurzorem nejsou v jistém pořadí. Řazené kurzory mohou být získány specifikací aktivního indexu pro kurzor (pomocí DbiOpenTable nebo DbiSwitchToIndex). Spuštěné dotazy s klauzulí ORDER BY jsou také řazené kurzory.
Když aplikace otevře kurzor na tabulce nebo výsledku dotazu, pak kurzor je umístěn na začátek výsledkové množiny, před první řádek v tabulce. Tato počáteční pozice umožňuje aplikaci přistupovat ke všem záznamům pomocí funkce DbiGetNextRecord. Kurzor může být umístěn na záznam nebo na mezeru před záznamem. Mezera je pozice mezi záznamy, na začátku tabulky, na konci tabulky nebo na místě po zrušeném záznamu.
Možné pozice kurzorů jsou: Záložka může být získána k uložení současné pozice kurzoru, což umožní pozdější návrat na toto místo. Záložky lze zapamatovat na libovolné pozici: na současném řádku, na začátku nebo na konci tabulky nebo na mezeře. Volání DbiGetBookMark ukládá současnou pozici kurzoru jako záložku. Následující volání DbiSetToBookMark umisťuje kurzor na místo uložené DbiGetBookMark. Na kurzoru může být umístěno více záložek. Pozice dvou záložek může být porovnávána voláním DbiCompareBookMark.
Dotazy SQL a QBE mohou být prováděny přímo nebo je nejprve připravíme a pak provedeme. Když dotaz je připraven, pak BDE testuje jeho přípustnost; pokud dotaz je přípustný, pak BDE vytváří objekt dotazu a vrací madlo příkazu dotazu. Po získání madla můžeme měnit jisté vlastnosti madla. Např. pokud dotaz má označovače parametrů, pak hodnoty parametrů mohou být nastaveny před provedením dotazu.

Databázové entity

Databázové entity jsou trvalé objekty, společné pro většinu databázových systémů a zahrnují: tabulky, indexy, položky, dotazy, transakce, zpětná volání a křížové databázové operace.
Data v databázi jsou organizovaná v tabulkách. V BDE jméno tabulky má význam pouze v databázi. Tabulky jsou dostupné z aplikace v řádcích (záznamech) a sloupcích (položkách). Řádky mohou být řazeny indexy. K vytvoření tabulky, aplikace volá funkci BDE DbiCreateTable předáním kompletní struktury popisu tabulky CRTblDesc. Případně, tabulky mohou být vytvářeny pomocí jazyka definice dat SQL (DDL).
Jisté databázové operace vytvářejí dočasné tabulky, které mohou být později uloženy na disk. Pokud tabulka získá značnou velikost, pak je automaticky zapsána na disk. Klientské aplikace mohou explicitně ukládat dočasné tabulky na disk voláním funkce DbiMakePermanent nebo DbiSaveChanges. Tyto tabulky se chovají jako normální tabulky.
DbiCreateInMemTable použijeme k vytvoření dočasné tabulky, kterou nezamýšlíme zapsat na disk. Jsou vytvářeny aplikací pro uložení informací, které jsou v průběhu zpracování stále zapotřebí. Tyto tabulky lze vytvořit pouze s logickými typy a nepodporují indexy.
Indexy určují pořadí záznamů v tabulce. Paradox, dBASE, FoxPro, Access a systémy SQL databází umožňují vytvářet indexy. Jsou ale rozdíly ve způsobu práce indexů a lisí se i informace nutné k definování indexů na těchto databázových systémech.
BDE podporuje všechny přirozené modely indexování v těchto systémech. K umožnění naši aplikaci vytvořit index, BDE poskytuje obecnou strukturu deskriptoru indexu IDXDesc. IDXDesc je svaz všech položek požadovaných k definování indexů pro všechny podporované systémy databáze. Pro přidání indexu, aplikace zapíše požadovaná data do IDXDesc a volá funkci DbiAddIndex.
K vytvoření indexu pro tabulku, naše aplikace požaduje pouze data v položkách deskriptoru indexu, které jsou aplikovatelné na databázový systém jisté tabulky. Např. když definujeme index pro tabulku InterBase, pak naše aplikace ignoruje položky jako jsou szTagName a szExpIdx, které se používají pouze k definování indexů dBASE. Pokud hodnoty požadovaných položek nejsou dodány, pak volání DbiAddIndex vrací chybovou zprávu.
Různé typy indexů v databázových systémech mají různé požadavky. Např. když přidáváme udržovatelný index dBASE, pak je vyžadována položka szTagName. Indexy mohou být také vytvářeny pomocí Jazyka definice dat SQL.
Jsou tři základní typy indexů: Indexy mají tři další charakteristiky: Je důležité pochopit, že různé ovladače podporují různé typy a charakteristiky indexů. Následuje seznam pravidel pro různé typy indexů a charakteristik podporovaných každým ovladačem.
dBASE
Následující pravidla popisují jak dBASE podporuje indexy: Paradox
Následující pravidla popisují jak Paradox podporuje indexy: SQL
Následující pravidla popisují jak ovladače SQL podporují indexy: Položky jsou sloupce tabulky. Vlastnosti každé položky v tabulce jsou definovány ve struktuře deskriptoru položky FLDDesc. Když tabulka je vytvářena DbiCreateTable, pak deskriptor tabulky CRTblDesc ukazuje na pole struktur FLDDesc, kde každá definuje položku v tabulce.
Fyzické datové typy se v jednotlivých typech datových zdrojů liší. Např. čísla v pohyblivé řádové čárce jsou ukládány různě v Paradoxu, dBASE a datových zdrojích SQL. Fyzické datové typy jednoho datového zdroje nemusí být kompatibilní s fyzickými datovými typy ostatních datových zdrojů pro uložení stejných dat.
Logické datové typy jsou obecné datové typy používané BDE. Tyto obecné typy jsou zaměnitelné mezi datovými zdroji, protože BDE je automaticky překládá na příslušné fyzické datové typy pro každý cílový datový zdroj.
Logické datové typy BDE jsou kompatibilní se standardními datovými typy jazyka C. Překladový algoritmus aplikace můžeme přepsat při zpřístupňování tabulky a tak získávat data ve fyzickém formátu použitým datovým zdrojem.
Obecné dotazovací moduly umožňují specifikovat dotazy v jazyku SQL nebo QBE na libovolném dostupném datovém zdroji. Prostřednictvím dotazů, BDE umožňuje uniformovat data získávaná prostřednictvím datových zdrojů. Lokální správce dotazu umožňuje spojovat data z různých serverů. Např. můžeme spojit Oracle s dBASE, Sybase s Paradoxem nebo InterBase s Oraclem na dvou různých serverech. Pro spuštění křížových databázových dotazů, jména tabulek v dotazu musí být kvalifikovány jmény přezdívek. Křížové databázové dotazy jsou podporovány pouze s madly standardních databází, pokud dotaz je cílen na SQL server.
BDE poskytuje množinu funkcí rozhraní dotazu, kterými vývojář aplikace se může dotazovat tabulek v dostupných databázích: BDE umožňuje přistupovat k datům SQL, Paradoxu, dBASE, FoxPro nebo Access prostřednictvím dotazů SQL (podmnožiny jazyka SQL) a dotazů QBE (jazyka Query By Example definovaného v Paradoxu). Oba typy dotazů mohou být prováděny jako živé výsledkové množiny (aktualizace se provedou i v původních tabulkách).
Transakce je skupina svázaných operací, které musí všechny proběhnout úspěšně nebo musí být všechny zrušeny. BDE podporuje transakce na všech serverech třemi funkcemi BDE: DbiBeginTran, DbiEndTran a DbiGetTranInfo.
Aplikace volá DbiBeginTran, předává příkazy SQL a funkce BDE vložené do transakce a pak volá DbiEndTran. DbiGetInfo vrací stavové informace o transakci.
BDE podporuje lokální transakce pro ovladače Paradoxu, dBASE a Access a tak aktualizované tabulky mohou být vráceny do původního stavu nebo zapsány trvale. Bez podpory transakcí, aktualizace jsou zapsány bezprostředně a není je možno zrušit.
Když lokální transakce je spuštěna na standardní databázi, pak aktualizace provedené na tabulkách v databázi jsou zaznamenány. Tento záznam obsahuje uložení původních záznamu, které byly změněny. Když transakce je aktivní, pak aktualizované záznamy jsou uzamčeny. Tyto zámky jsou drženy dokud transakce není trvale zapsána nebo zrušena. Pro standardní databáze neexistuje automatické zotavení z chyb.
Někdy klientská aplikace požaduje informace o zpracování dané funkce. Např. pokud tabulka je restrukturalizována, pak jisté podmínky mohou způsobit zápis záznamů do "problémové" tabulky místo do cílové tabulky. V těchto situacích můžeme chtít ukončit operaci nebo provést nějakou jinou akci. Zpětné volání umožňuje aplikaci vyhodnotit situaci před předáním akce BDE. Aplikace registruje zpětná volání voláním DbiRegisterCallBack.
Po registraci zpětného volání, výskyt specifikované události spouští zpětně volanou funkci. Zpětné volání pak zjistí další instrukce pro aplikaci. Klient reaguje na zpětné volání zasláním příslušného návratového kódu (cbrABORT, cbrCONTINUE apod.). Mechanismus zpětného volání je efektivní, protože BDE může získat reakci aplikace bez přerušení normálního procesu zpracování.
Dotazy a dávkové funkce BDE mohou operovat na heterogenních datových zdrojích. Následující příklady ukazují tyto služby:

Vývoj aplikací

Budeme se seznamovat se základní kroky vývoje aplikací s BDE.
Úvod do programování BDE
Nyní si ukážeme jak začít programovat BDE. Po provedení následujících kroků budeme mít jednoduchou aplikaci, která získá záznam z tabulky a zobrazí první dvě položky.
Pro tuto jednoduchou aplikaci nastavíme cílové prostředí na konzolovou aplikaci. Nebudeme se tedy muset zabývat uživatelským rozhraním Windows. Nastavíme volbu překladu "Allocate enums as ints". Do modulu obsahující kód BDE vložíme hlavičkové soubory: WINDOWS.H a IDAPI.H.
Následují základní kroky potřebné k získání záznamu z tabulky. Celý program si můžeme prohlédnout zde.

Zpřístupňování a aktualizace tabulek

Následující tabulka uvádí procesy zpřístupňování a aktualizace tabulek pomocí BDE:
 
Fáze Úloha Funkce BDE
Příprava Inicializace modulu přístupu k databázi (BDE) DbiInit
Příprava Otevření databáze DbiOpenDatabase
Příprava Otevření tabulky a získání kurzoru DbiOpenTable
Příprava Získání vlastností kurzoru DbiGetCursorProps
Příprava Alokování vyrovnávací paměti záznamu Zodpovídá aplikace
Příprava Získání deskriptoru položky DbiGetFieldDescs
Příprava Zahájení režimu odložených aktualizací DbiBeginDelayedUpdates
Získávání Umístění ukazatele a získání záznamu do vyrovnávací paměti DbiGetNextRecord
Získávání Získání položky z vyrovnávací paměti DbiGetField
Aktualizace Aktualizace položky a zápis do vyrovnávací paměti záznamu DbiPutField
Aktualizace Aktualizace tabulky novým záznamem DbiModifyRecord
Aktualizace Aplikování odložených změn na tabulku DbiApplyDelayedUpdates
Ukončení Ukončení režimu odložených aktualizací DbiEndDelayedUpdates
Ukončení Uzavření kurzoru DbiCloseCursor
Ukončení Uzavření databáze DbiCloseDatabase
Ukončení Ukončení BDE (modulu přístupu k databázi) DbiExit
Příprava na přístup k tabulce
Prvním voláním, které aplikace provádí na BDE je vždy DbiInit, k inicializaci modulu přístupu k databázi a spuštění nového sezení. DbiInit může být volitelně použito s ukazatelem na informační strukturu prostředí DBIEnv. Normálně je předáván ukazatel NULL, čímž donutíme BDE hledat položky v Registrech a v konfiguračním souboru BDE a použití implicitního nastavení. Pokud předáme ukazatel NULL na strukturu DBIEnv, pak BDE hledá konfigurační soubor takto:
  1. BDE testují Registry Windows na konfigurační soubor definovaný položkou [BDE] s podpoložkou CONFIGFILE01.
  2. Pokud krok 1 není úspěšný, pak BDE hledá konfigurační soubor jména IDAPI.CFG ve spouštěcím adresáři.
  3. Pokud krok 2 není úspěšný, pak BDE je inicializováno implicitním nastavením preferovaným pro každý ovladač.
Jestliže ukazatel není NULL a konfigurační soubor je specifikován ve struktuře DBIEnv, pak BDE použije tento konfigurační soubor. Následuje příklad volání DbiInit:
rslt = DbiInit(NULL);
Dříve než můžeme otevřít tabulku musíme voláním DbiOpenDatabase otevřít databázi. Úspěšné volání DbiOpenDatabase vrací madlo databáze, které je dále předáváno následujícím voláním mnoha funkcí BDE.
Pro SQL databáze musí být s DbiOpenDatabese dodáno jméno uživatele a heslo pro připojení k serveru.
Následující příklad kódu otevírá standardní databázi pomocí nastavení jména databáze a typu databáze na NULL:
rslt = DbiOpenDatabase(NULL, NULL, dbiREADWRITE,
       dbiOPENSHARED, NULL, 0, NULL, NULL, &hDb)
Pro změnu současného adresáře pro standardní databázi voláme DbiSetDirectory:
rslt = DbiSetDirectory(hDb, "C:\\DATE");
Je několik různých metod specifikace SQL databáze ve volání DbiOpenDatabase: Např. tento kód otevírá pojmenovanou databázi na SQL serveru:
rslt = DbiOpenDatabase("myalias", NULL, dbiREADWRITE, dbiOPENSHARED,
                       "mypassword", 0, NULL, NULL, &hDb)
Když voláme DbiOpenDatabase, pak můžeme předat přezdívku odkazující se na jméno databáze v konfiguračním souboru.
Parametry eOpenMode a eShareMode volání DbiOpenDatabase v kombinaci s parametry eOpenMode a eShareMode volání DbiOpenTable určují přístupová práva uživatelů k tabulkám v databázi.
Pro datové zdroje SQL, parametr OPEN MODE pro každou přezdívku v konfiguračním souboru BDE má přednost před parametry režimu otevření předaným v DbiOpenDatabase.
Pokud režim otevření je pouze pro čtení, pak tabulky v databázi není možno otevřít v režimu čtení i zápis. Když databáze je otevřena v režimu čtení i zápis, pak tabulky v databázi mohou být otevírány DbiOpenTable v režimu pouze pro čtení i v režimu čtení i zápis.
Pokud režim sdílení databáze je výlučný, pak tabulky v databázi nemohou být otevírány DbiOpenTable ve sdíleném režimu. Pokud databáze je otevřena ve sdíleném režimu, pak tabulky v databázi mohou být otevírány DbiOpenTable ve výlučném nebo sdíleném režimu.
Volitelné parametry závisející na databázi mohou být předávány funkci DbiOpenDatabase. Pro získání seznamu a popisu těchto volitelných parametrů pro databáze, aplikace může volat DbiOpenCfgInfoList, předáním cesty ke jménu databáze v konfiguračním souboru. Tato funkce vrací madlo na virtuální tabulku volitelných parametrů pro tento databázový systém a implicitní hodnoty těchto parametrů.
OptFields, pOptFldDesc a pOptParams jsou volitelné parametry, ale mohou být aktuálně vyžadovány v závislosti na použitém ovladači.
Tabulku můžeme otevřít voláním DbiOpenTable a předáním příslušných parametrů jako je jméno tabulky, typ ovladače, index, typ přístupu a režim sdílení. Po úspěšném otevření tabulky, BDE vrací madlo kurzoru k tabulce.
Pokud aplikace předává plně kvalifikované jméno tabulky Paradoxu nebo dBASE, pak nemusí specifikovat parametr typu ovladače, protože typ ovladače může být určen z přípony jména souboru. Pokud jméno tabulky neobsahuje cestu, pak je použit současný adresář databáze přiřazené k madlu databáze.
Typ ovladače musí být specifikován, pokud jméno tabulky nemá příponu nebo k přepsání implicitního ovladače přiřazeného k příponě souboru nebo k ukončení jména tabulky tečkou. Pokud jméno tabulky nepodporuje implicitní příponu a parametr typu ovladače je NULL, pak DbiOpenTable se pokusí otevřít tabulku s implicitní příponou souboru určenou pro každý souborový ovladač uvedený v konfiguračním souboru, v pořadí uvedení ovladačů. Typy ovladačů a jejich implicitní přípony pro ovladače Paradoxu, dBASE a Text již byly uvedeny.
Pro SQL databáze, jméno tabulky může být plně kvalifikované jméno, které obsahuje jméno vlastníka ve tvaru
<vlastník>.<jméno_tabulky>
Pokud není specifikován, pak vlastník je určen z madla databáze. Typ ovladače je ignorován, pokud databáze je SQL databáze, neboť ovladač při otevření databáze je již určen. Pro databáze Access, jsou požadovány typ ovladače a identifikátor tabulky.
Pro otevření tabulky s aktivním indexem, můžeme použít následující parametry, závisející na typu otevírané tabulky: pszIndexName, pszIndexTagName nebo iIndexId. Aktivní index určuje pořadí záznamů pro tento kurzor.
Paradox: Pokud všechny parametry indexů jsou NULL, pak tabulka je otevřena v pořadí primárního klíče (pokud existuje). Pokud je specifikován sekundární klíč, tak tabulka je otevřena na tomto klíči. pszIndexName nebo iIndexID může být použito pro specifikaci složeného nebo nesloženého sekundárního klíče.
Access: Pokud všechny parametry indexů jsou NULL, pak tabulka je otevřena v přirozeném pořadí. pszIndexName nebo iIndexID může být použito pro specifikaci složeného nebo nesloženého sekundárního klíče.
dBASE a FoxPro: Pokud index není specifikován, pak tabulka je otevřena ve fyzickém pořadí.
SQL: Použijeme parametr pszIndexName pro specifikaci jména indexu. Jméno indexu může být kvalifikováno nebo nekvalifikováno. Nekvalifikované jméno indexu je úspěšné pouze když vlastník indexu je současný uživatel.
Tabulka může být otevřena v režimu EXCLUSIVE nebo SHARED. Když tabulka je otevřena ve výlučném režimu, pak další uživatelé nemohou přistupovat k tabulce. Když tabulka je otevřena v režimu sdílení, pak k tabulce mohou přistupovat ve stejné době i ostatní uživatelé.
Je doporučován režim překladu xltFIELD. Tento režim zajišťuje, že BDE automaticky překládá data z přirozeného fyzického datového formátu databáze na společný logický formát BDE, když jsou čteny záznamy. BDE překládá data zpět do přirozeného formátu, když položky jsou zapisovány. Když je určen překladový režim xltNONE, pak překlady nejsou při čtení a zápisu záznamů prováděny.
Překlad dat nastává pouze v průběhu volání DbiGetField a DbiPutField; a ne při čtení záznamů.
Úspěšné volání DbiOpenTable vrací madlo kurzoru aplikaci. Dříve než můžeme použít madlo kurzoru pro přístup k datům v tabulce, aplikace musí připravit vyrovnávací paměť záznamu. Tato příprava zahrnuje alokaci paměti pro záznam a v některých případech její inicializaci.
Aplikace může také nastavit pole do kterého budou pro každou položku z tabulky vloženy deskriptory položek. K určení požadované velikosti vyrovnávací paměti záznamů a pole deskriptorů položek aplikace volá DbiGetCursorProps. Toto volání obvykle následuje bezprostředně po volání DbiOpenTable a vrací požadované informace ve struktuře CURProps.
Následující kód získává vlastnosti kurzoru, alokuje vyrovnávací paměť záznamu, nastavuje pole pro deskriptory položek a získává deskriptory položek:
DBIResult   rslt;
pCHAR       pRecBuf;
CURProps    curProps;
pFLDDesc    pFldArray;
...
// Získání vlastností tabulky
rslt = DbiGetCursorProps(hCursor, &curProps);
if (rslt == DBIERR_NONE)
{
  // Alokace vyrovnávací paměti záznamu
  pRecBuf = malloc(curProps.iRecBufSize);
  // Testování výsledku alokace
  ...
  // Získání pole deskriptorů položek
  pFldArray=(pFLDDesc)malloc(sizeof(FLDDesc)*curProps.iFields);
  // Testování výsledků alokace
  ...
  rslt = DbiGetFieldDescs(hCursor, pFldArray);
  ...
  free(pFldArray);
  free(pRecBuf);
}
Když aplikace volá DbiGetCursorProps, pak je vrácena struktura vlastností kurzoru CURProps s informacemi popisujícími nejčastěji používané vlastnosti kurzoru. CURProps obsahuje následující položky:
 
Typ Jméno Popis
DBITBLNAME szName Jméno tabulky 
UINT16 iFNameSize Plná velikost jména souboru
DBINAME szTableType Typ tabulky
UINT16 iFields Počet položek v tabulce
UINT16 iRecSize Velikost záznamu (logický záznam)
UINT16 iRecBufSize Velikost záznamu (fyzický záznam)
UINT16 iKeySize Velikost klíče
UINT16 iIndexes Počet současně dostupných indexů
UINT16 iValChecks Počet testů přípustnosti
UINT16 iRefIntChecks Počet omezení referenční integrity
UINT16 iBookMarkSize Velikost záložky
BOOL bBookMarkStable true, pokud kurzor podporuje trvalé záložky
DBIOpenMode eOpenMode dbiREADWRITE, dbiREADONLY
DBIShareMode eShareMode dbiOPENSHARED, dbiOPENEXCL
BOOL bIndexed true, pokud index je aktivní
INT16 iSeqNums 1: má sekvenční čísla (Paradox), 0: má čísla záznamů (dBASE, FoxPro), <0 (-1,-2,...): nic (SQL a Access).
BOOL bSoftDeletes true, pokud kurzor podporuje měkké rušení (pouze dBASE a FoxPro)
BOOL bDeletedOn true, pokud zrušené záznamy jsou viditelné
UINT16 iRefRange Pokud > 0, pak má aktivní obnovení
XLTMode exltMode Překladový režim: xltNONE (fyzické typy), xltFIELD (logické typy)
UINT16 iRestrVersion Číslo verze
BOOL bUniDirectional true, pokud kurzor je jednosměrný (pouze SQL)
PRVType eprvRights Tabulková úroveň práv
UINT16 iFmlRights Rodinná práva (pouze Paradox)
UINT16 iPasswords Počet pomocných hesel (pouze Paradox)
UINT16 iCodePage Kódová stránka (0 pokud není známa)
BOOL bProtected true, pokud tabulka je chráněna heslem
UINT16 iTblLevel Na ovladači závislá tabulková úroveň
DBINAME szLangDriver Symbolické jméno jazykového ovladače
BOOL bFieldMap true, pokud mapování položek je aktivní
UINT16 iBlockSize Velikost datového bloku ve slabikách (je-li)
BOOL bStrictRefInt true, pokud se vyžaduje přesná referenční integrita
UINT16 iFilters Počet filtrů
BOOL bTempTable true, pokud tabulka je dočasná

Když alokujeme paměť, pak jsou významné následující prvky:

Pokud má být vložen nový záznam, pak inicializujeme vyrovnávací paměť záznamu voláním DbiInitRecord. Tato funkce inicializuje každou položku ve vyrovnávací paměti záznamu, včetně položek BLOB, na prázdné hodnoty založené na definovaných datových typech. Pro tabulky Paradoxu, implicitní hodnoty jsou použity k inicializaci položek, pokud v tabulce jsou specifikovány implicitní hodnoty.
Po alokování paměti pro pole deskriptorů položek, může aplikace získat deskriptory položek voláním DbiGetFieldDescs. Deskriptory položek poskytují informace, které jsou potřebné k adresování a manipulaci s položkami ve vyrovnávací paměti záznamů. DbiGetFieldDescs vrací pole struktur FLDDesc, s informacemi popisujícími každou položku v tabulce:
 
Typ Jméno Popis
UINT16 iFldNum Číslo položky (1 až n)
DBINAME szName Specifikuje jméno položky.
UINT16 iFldType Specifikuje typ položky. V závislosti na překladovém režimu kurzoru je vracen fyzický nebo logický typ položky. 
UINT16 iSubType Specifikuje podtyp položky. To může být logický podtyp BDE nebo fyzický podtyp ovladače v závislosti na překladovém režimu.
UINT16 iUnits1 Specifikuje počet znaků, číslic apod. Pro logické typy položek, toto číslo je konzistentní přes ovladače. Pro fyzické typy položek, interpretace závisí na ovladači. Pro většinu ovladačů iUnits1 je přesnost a iUnits2 je měřítko.
UINT16 iUnits2 Specifikuje počet desetinných míst, apod. Viz specifikace pro iUnits1.
UINT16 iOffset Specifikuje ofset této položky ve vyrovnávací paměti záznamu. Závisí na překladovém režimu.
UINT16 iLen Specifikuje délku této položky. Závisí na překladovém režimu.
UINT16 iNullOffset Specifikuje ofset indikátoru NULL pro tuto položku ve vyrovnávací paměti záznamu. Při nule není indikátor NULL.
FLDVchk efldvVchk Specifikuje zda k položce je přiřazen test přípustnosti.
FLDRights efldrRights Specifikuje přístupová práva pro položku.
iFldNum Specifikuje ID položky závisející na ovladači. Pro většinu ovladačů je to hodnota od 1 do curProps.iFields, mimo tabulek Paradoxu.

Pro konzistentnost nad ovladači, používáme pořadí položky v poli deskriptorů. DbiGetField a DbiPutField používají pořadová čísla od 1 do n.

Umisťování kurzoru a získávání záznamů
Po připravení vyrovnávací paměti záznamů, aplikace ji může využít k získávání záznamů z tabulky. K získání záznamu, aplikace musí umístit kurzor na záznam, který chce získat. Některé funkce BDE slouží pouze k umisťování kurzoru. Volání těchto funkcí může následovat volání funkce, která získá záznam do vyrovnávací paměti. Další funkce BDE mohou současně přemisťovat kurzor a získávat záznamy.
Některé funkce BDE umisťují kurzor před záznam, na začátek (nebo konec) souboru nebo výsledkové množiny. Když kurzor je umístěn na některou z těchto pozicí, namísto na záznam, pak říkáme, že kurzor je umístěn na mezeru. Následující volání umisťují kurzor na mezeru: Umisťování kurzoru na mezeru může zjednodušit programování. Např. voláním DbiSetToBegin umístíme kurzor na mezeru před první záznam v tabulce. Pak můžeme v cyklu zpracovat všechny záznamy v tabulce voláním DbiGetNextRecord.
Některé funkce BDE umisťují kurzor přímo na záznam. Pokud je poskytnuta vyrovnávací paměť záznamu, pak tyto funkce mohou být také použity k získávání záznamů pro zpracování aplikací. Mnoho těchto volání může volitelně uzamknout záznam. Záznamy zůstávají uzamčeny dokud nejsou explicitně uvolněny nebo dokud není uzavřeno sezení. Následující příklad ukazuje jak umístit kurzor na začátek souboru a procházet tabulkou:
// Umístění kurzoru na začátek souboru
DbiSetToBegin(hCursor);
// Procházení tabulkou. Při každém průchodu čtení záznamu.
while (DbiGetNextRecord(hCursor, dbiNOLOCK, pRecBuf, NULL)
       == DBIERR_NONE)
{
  ...
}
Záložky poskytují možnost uložit pozici kurzoru a mít možnost se později vrátit na stejné místo. Záložky jsou zapsány do vyrovnávací paměti, která je alokována klientem. Velikost vyrovnávací paměti záložek se může změnit po volání DbiSwitchToIndex. Aplikace může získávat více záznamů jedním voláním při nastavení velikosti vyrovnávací paměti pro několik záznamů a voláním DbiReadBlok. Je získám specifikovaný počet záznamů počínaje následujícím záznamem za současnou pozicí kurzoru. Tato funkce je ekvivalentní cyklu, který provádí volání DbiGetNextRecord.
Několik funkcí BDE umožňuje vnutit kurzoru návrat pouze omezené množiny záznamů nebo položek aplikaci; tj. aplikace vidí pouze ty záznamy v tabulce, které splňují předdefinovanou množinu podmínek. Dotazy poskytují další způsob návratu omezené množiny záznamů.
DbiSetRange použijeme k donucení kurzoru aby vracel aplikaci pouze ty záznamy jejichž klíč je v definovaném  rozsahu. Tato funkce může být volána pouze pokud kurzor má aktivní index. Mohou být definovány zahrnující a vylučující rozsahy. Následující volání BDE pak získává množinu záznamů v rozsahu, jako kompletní tabulku. Např. DbiSetToBegin umístí kurzor na mezeru před prvním záznamem v rozsahu místo před první záznam v tabulce.
Tato funkce je často používána k nalezení množiny záznamů mezi dvěmi hodnotami klíčů nastavením dolní a horní meze rozsahu. Může být také specifikován otevřený rozsah, od začátku souboru do specifikovaného klíče nebo od specifikovaného klíče do konce souboru.
DbiSetFieldMap použijeme k donucení kurzoru aby vracel položky v jiném pořadí než jsou uvedeny v tabulce nebo k vypuštění položek ze zobracení. K nastavení mapy položek, vývojář aplikace vytvoří pole deskriptorů položek, do kterého vloží pouze ty položky, které mají být viditelné kurzorem a v pořadí ve kterém mají být vráceny. Pouze položky uvedené v poli jsou viditelné. Vytvořením mapy položek můžeme změnit velikost záznamové vyrovnávací paměti.
Aktivní filtr vnucuje kurzoru návrat omezené množiny záznamů (pouze těch, které splňují podmínku filtru). Záznamy nesplňující podmínku filtru jsou přeskočeny i když v tabulce stále zůstávají (nejsou pouze viditelné kurzorem). Po deaktivaci filtru jsou viditelné opět všechny záznamy.
Podmínky filtrů jsou definovány tak, aby vracely true nebo false. Když filtr je aktivován, pak výraz filtru je aplikován na všechny záznamy v tabulce. Viditelné jsou pouze ty, pro které je vráceno true. Na jednu tabulku může být definováno více filtrů.
Pro definici filtru aplikace volá DbiAddFilter, předává existující madlo kurzoru a ukazatel na strukturu CANExpr, která obsahuje výraz. Struktura CANExpr může obsahovat operátory porovnávání, AND, OT a NOT a testy na prázdné položky. Různé ovladače mohou obsahovat různé typy výrazů, ale všechny podporují základní kombinaci: <položka><porovnávací operátor><konstanta>; např. "field1 = 'CA' and field2 < 30". Po dokončení DbiAddFilter je aplikaci vráceno madlo filtru.
Po definování podmínky filtru musí být filtr aktivován DbiActivateFilter aby se projevil. Může být aktivováno více filtrů. Filtry mohou být zapínány a vypínány podle potřeby (pomocí DbiActivateFilter a DbiDeactivateFilter). Filtry jsou automaticky zrušeny při uzavření kurzoru a mohou být zrušeny explicitně voláním DbiDropFilter.
Přístup na úrovni položek
Aplikace obvykle zpřístupňuje data v záznamu na úrovni položek. Funkce BDE DbiGetField a DbiPutField umožňují aplikaci získávat a aktualizovat data v položkách ve vyrovnávací paměti záznamu. Tyto funkce umožňují přistupovat k položkám bez nutnosti znát strukturu vyrovnávací paměti záznamu.
Pro získání položky z vyrovnávací paměti záznamu, aplikace volá funkci DbiGetField, předá pořadové číslo položky a vyrovnávací paměť k uložení dat obsažených v položce (položky jsou číslovány od 1). Volitelně může být vrácena logická hodnota indikující prázdnou položku.
K aktualizaci položky ve vyrovnávací paměti záznamů, aplikace volá DbiPutField, předá pořadové číslo položky a vyrovnávací paměť obsahující obsah položky zapisovaný do záznamu. DbiPutField může být také použita k vyprázdnění položky, předáním ukazatele NULL jako parametru vyrovnávací paměti položky.
Když překladový režim položek je aktivní (xltFIELD), pak BDE automaticky překládá obsah dat položek. Když položka je získávána, pak BDE přeloží data ve vyrovnávací paměti záznamu z přirozeného typu dat na obecné logické datové typy. Při zpětném zápisu položek do vyrovnávací paměti záznamu je proveden zpětný překlad na přirozené fyzické datové typy.
Pokud překladový režim položek není uplatněn, pak BDE neprovádí překlad na logické datové typy. Aplikace potom musí být připravena akceptovat data v přirozených datových typech.
 
Typ BDE Ekvivalent C Popis
fldZSTRING char[ ] Nulou ukončené pole znaků.
fldUINT16 unsigned int 16 bitové celé číslo bez znaménka.
fldINT16 int 16 bitové celé číslo.
fldUINT32 unsigned long  32 bitové celé číslo bez znaménka.
fldINT32 long 32 bitové celé číslo.
fldFLOAT double 64 bitové číslo v pohyblivé řádové čárce.
fldFLOATIEEE long double  80 bitové číslo v pohyblivé řádové čárce.
fldBOOL int 16 bitová hodnota, true =1; false = 0.
fldBYTES unsigned char[ ]  Pole slabik pevné délky.
fldVARBYTES unsigned char[ ] Délkou předcházené pole slabik.

Práce s BLOB

Protože velikost položek BLOB může být značně velká, BDE s nimi pracuje jinak než s ostatními položkami; jsou chápány jako proudy slabik. Pro práci s položkami BLOB se používají následující funkce BDE: DbiOpenBlob, DbiGetBlob, DbiGetBlobHeading, DbiGetBlobSize, DbiFreeBlob, DbiPutBlob a DbiTruncateBlob.
Pro zápis do nebo čtení z BLOB je nutno nejprve BLOB otevřít. Pro otevření BLOB, vyrovnávací paměť záznamu musí obsahovat kopii modifikovaného záznamu nebo vkládaného záznamu (pokud záznam bude vkládán). Aplikace volá DbiOpenBlob, předá madlo kurzoru, ukazatel na vyrovnávací paměť záznamu, číslo položky BLOB a přístupová práva (pokud BLOB je otevírán pro čtení i zápis, pak tabulka musí být otevřena také pro čtení i zápis). DbiOpenBlob ukládá madlo BLOB ve vyrovnávací paměti záznamu. DbiOpenBlob musí být volána dříve než můžeme volat ostatní funkce BLOB.
DbiGetBlob získává data BLOB ze specifikovaného BLOB. Může být získána pouze část dat, počínaje od pozice specifikované v iOffSet a délce v počtu slabik specifikované v iLen. Aplikace obvykle nezná délku BLOB a tedy provádí řadu volání DbiGetBlob k získání celého BLOB. DbiGetBlob vrací počet skutečně přečtených slabik a porovnáním této hodnoty s požadovaným počtem čtených slabik lze zjistit konec BLOB. Aplikace může případně zjistit velikost BLOB předem voláním DbiGetBlobSize a potom specifikovat aktuální délku ve volání DbiGetBlob (v tomto případě celý BLOB získáme jedním voláním DbiGetBlob).
DbiPutBlob je používán k zápisu dat do BLOB. BLOB musí být otevřen v režimu čtení i zápis. Aplikace předává ukazatel na blok dat, která mají být zapsána. Aplikace specifikuje délku zapisovaných dat a také ofset v BLOB od kterého začneme zapisovat data. Aplikace může použít řadu volání DbiPutBlob k zápisu celého BLOB.
K aktualizaci nebo přidávání záznamu, aplikace provede tyto kroky:
  1. Volá DbiAppendRecord nebo DbiInsertRecord pro přidání nového záznamu s BLOB k tabulce nebo aplikace volá DbiModifyRecord k modifikaci existujícího záznamu obsahujícího BLOB. Ukazatel na vyrovnávací paměť záznamu obsahující nový záznam je předán funkci.
  2. Volá DbiFreeBlob k uzavření madla BLOB a všech zdrojů alokovaných pomocí DbiOpenBlob (DbiModifyRecord, DbiInsertRecord nebo DbiAppendRecord neuvolňují automaticky zdroje BLOB po modifikaci záznamu). Pokud DbiFreeBlob voláme před DbiModifyRecord, DbiInsertRecord nebo DbiAppendRecord, pak změny jsou ztraceny.
Pro tabulky obsahující BLOB nesmíme používat DbiWriteBlock.
Následující příklad ukazuje zpracování BLOB:
DBIResult   rslt;
pCHAR       blobBuf;
UINT32      blobSize, bytesRead;
// čtení současného záznamu
DbiGetRecord(hCursor, dbiNOLOCK, pRecBuf, NULL);
// otevření BLOB
rslt = DbiOpenBlob(hCursor, pRecBuf, 3, dbiREADWRITE);
if (rslt == DBIERR_NONE)
{
  // Získání velikosti BLOB a jeho přečtení.
  // Zde předpokládáme,BLOB je menší než 64K.
  DbiGetBlobSize(hCursor, pRecBuf, 3, &blobSize);
  blobBuf = malloc(blobSize);
  DbiGetBlob(hCursor, pRecBuf, 3, 0, blobSize,
             (pBYTE) blobBuf, &bytesRead);
  ...
  // Uvolnění BLOB
  DbiFreeBlob(hCursor, pRecBuf, 3);
  // Uklid
  free(blobBuf);
}
Přidávání, aktualizace a rušení záznamů
Pro přidávání, aktualizaci a rušení záznamů, musí mít kurzor zápisový přístup k tabulce. Tabulka nebo záznam nesmí být uzavřen jiným uživatelem. Pokud aplikace modifikuje záznam, pak jej může při jeho získání uzamknout. Záznam zůstává uzamčen, pokud jej aplikace explicitně neuvolní nebo dokud sezení není uzavřeno. Můžeme také použít odložené aktualizace bez přímého zápisu do databáze. To minimalizuje množství uzamčených zdrojů.
Pro přidání nového záznamu k tabulce, aplikace provádí následující kroky:
  1. Inicializuje klientem alokovanou vyrovnávací paměť záznamů voláním DbiInitRecord.
  2. Vytváření položek záznamů po jedné použitím DbiPutField.
  3. Voláme DbiAppendRecord nebo DbiInsertRecord k zápisu obsahu vyrovnávací paměti do tabulky. Aplikace specifikuje zda na vloženém záznamu má být držen zámek (DbiInsertRecord).
K modifikaci existujícího záznamu v tabulce, aplikace provádí tyto kroky:
  1. Získáme modifikovaný záznam do klientem alokované vyrovnávací paměti (získaný záznam můžeme uzamkount).
  2. Zapíšeme aktualizované položky do vyrovnávací paměti záznamů pomocí DbiPutField.
  3. Voláme DbiModifyRecord k zápisu vyrovnávací paměti záznamu do tabulky. Aplikace specifikuje zda uvolní zámek po dokončení aktualizace záznamu.
Pro zrušení záznamu aplikace provádí kroky:
  1. Umístí kurzor na rušený záznam.
  2. Volá DbiDeleteRecord. Pokud záznam je umístěn ve vyrovnávací paměti, pak je zrušen i zde.
  3. Kurzor je přemístěn na mezeře po zrušeném záznamu.
Následuje několik poznámek:
Spojování tabulek
Spojované kurzory umožňují vytvořit vzájemný vztah master - detail mezi tabulkami. Kurzory na dvou tabulkách mohou být spojeny, pokud tabulky sdílejí společnou položku, která v tabulce detail musí být indexována. Spojením kurzoru na tabulce master a tabulce detail zajistí, že pro kurzor na tabulce detail jsou viditelné pouze ty záznamy jejichž hodnota klíče se shoduje s hodnotou klíče v současném záznamu tabulky master.
Např. tabulka CUSTOMER (master) a tabulka ORDERS (detail) sdílí společnou položku nazvanou CUSTOMER_NO. Pokud současný záznam v tabulce master má hodnotu CUSTOMER_NO rovnou 1221, pak v tabulce detail jsou viditelné pouze ty záznamy u nichž CUSTOMER_NO je rovno 1221.
Tabulka master může být spojena s více než jednou tabulkou detail, ale tabulka detail může být spojena pouze s jednou tabulkou master. Tabulka detail může být také tabulkou master spojenou na další tabulky detail. Spojování je aplikovatelné na všechny dostupné typy ovladačů a může být zřízeno mezi tabulkami stejných nebo rozdílných typů.
Pro spojení dvou tabulek aplikace provede tyto kroky:
  1. Aplikace otevře kurzory na obou tabulkách. Kurzor tabulky detail musí mít aktivní index na položce, která bude použita ke spojení kurzorů.
  2. Aplikace volá DbiBeginLinkMode pro každý spojovaný kurzor. Funkce vrací nový kurzor.
  3. Aplikace volá DbiLinkDetail a předává madla kurzorů tabulek master a detail. Datové typy spojovaných položek v záznamech master a detail se musí shodovat. Tuto funkci nelze použít pro výrazové indexy (pro výrazové indexy tabulek dBASE nebo FoxPro musíme použít DbiLinkDetailToExp).
  4. Dva kurzory jsou nyní spojeny. Když přemisťujeme kurzor master, pak odpovídající kurzor detail se mění k zobrazení aplikovatelných záznamů.
K přerušení spojení mezi kurzory, aplikace provádí:
  1. Aplikace volá DbiUnLinkDetail a předává madlo kurzoru tabulky detail. Tabulka detail je nyní odpojena od tablky master a její kurzor zobrazuje celý rozsah záznamů.
  2. Aplikace volá DbiEndLinkMode pro každý spojovaný kurzor a předává madlo kurzoru. Je vráceno standardní madlo kurzoru.
Řazení tabulek
Řadící funkce BDE DbiSortTable řadí otevřené nebo uzavřené tabulky a to jak na sobě nebo v cílové tabulce. Jsou volby k odstraňování duplicit, k umožnění řazení s rozlišením velikosti písmen, k řazení podmnožiny položek a k poskytnutí speciální uživatelem definované řadící funkce. DbiSortTable je také podporována ovladači SQL, ale tabulky SQL mohou sloužit pouze jako zdrojové tabulky a ne jako cílové. K určení řadícího pořadí je použit jazykový ovladač.
Odložené aktualizace
Odložené aktualizace umožňují uživateli získávat data z databáze a provádět změny, které jsou ukládány a to bez přímého zápisu do databáze. Uživatel může provádět změny v delším časovém intervalu s minimálním uzamykaním zdrojů v aktuální databázi. Po modifikaci dat, uživatel volá aktualizační funkci k uložení změn do aktuální databáze. Aktualizační funkce zasílá do databáze dávku všech vkládání, rušení a modifikací provedených do volání aktualizační funkce.
Vrstva odložených aktualizací udržuje všechny změny, které jsou provedeny použitím kombinací různých metod tabulky, jako je vkládání záznamů, modifikace záznamů a rušení záznamů. Jak procházíme tabulkou, vrstva odložených aktualizací zajišťuje, že vidíme modifikované, zrušené a vložené záznamy. Aktualizace ale nejsou bezprostředně zasílány do připojené tabulky, jsou odloženy vrstvou odložených aktualizací. Žádné záznamové zámky nejsou drženy dokud odložené aktualizace nejsou trvale zapsány. Potom zámky jsou drženy pouze v průběhu trvalého zápisu.
Protože záznamové zámky nejsou drženy před operací trvalého zápisu, riskujeme, že některé záznamy mohly být změněny ostatními uživateli. Pokud záznam modifikovaný vrstvou odložených aktualizací je modifikován ostatními uživateli před trvalým zápisem odložených aktualizací, pak je vrácena chyba, indikující, že záznam byl modifikován jiným uživatelem.
Pro tabulky standardních databází, každá ne-BLOB položka může být použita k provádění modifikace záznamu. Po provedení požadovaných změn, klient volá DbiApplyDelayedUpdates pro trvalý zápis nebo změny zruší. Operace rušení rychle zruší aktualizační informace v cache.
Pokud se uživatel rozhodne trvale zapsat změny, pak aktualizace jsou aplikovány na databázi. Při aplikování aktualizací je prováděno testování přípustnosti referenční integrity a dat. Mechanismus zpětného volání informuje uživatele o porušení integrity dat. Tento mechanismus může přeskočit jisté chybné aktualizace nebo zrušit celou operaci trvalého zápisu.
Vrstva odložených aktualizací pracuje v průběhu času na jednou kurzoru. Pokud klienty chtějí podporovat odložené aktualizace ve formě operací na více než jednom kurzoru, pak klient zodpovídá za synchronizaci odložených aktualizací na různých kurzorech. Některá volání BDE, které provádějí operace na tabulkách nejsou podporovány vrstvou odložených aktualizací, včetně volání BDE řadících data, jako je DbiSwitchToIndex. To může být provedeno před zadáváním odložených aktualizací. Vrstva odložených aktualizací závisí na záložkách k držení stopy k modifikovaným záznamům. Protože záložky se mění voláním DbiSwitchToIndex, jsou tato volání BDE zakázána.
Používání režimu odložených aktualizací je dvoufázový proces. V první fázi příkaz dbiDelayedUpdPrepare se pokusí aplikovat všechny změny na připojená data. Pokud jej použijeme v jednouživatelském prostředí, pak tento příkaz je vždy použit v kontextu transakce k zotavení chyb v průběhu aktualizace. Všechny chyby vzniklé v průběhu této fáze jsou zpracovány prostřednictvím funkcí zpětného volání.
Příkaz dbiDelayedUpdateCommit provádí druhou fázi. Po úspěšném volání dbiDelayedUpdPrepare přímo následuje příkaz dbiDelayedUpdateCommit. Interní cache zohledňuje fakt, že aktualizace byly úspěšně aplikovány na připojenou databázi (úspěšně aplikované záznamy jsou odstraněny z cache).
K vytvoření režimu odložených aktualizací:
  1. Vytvoříme vrstvu odložaných aktualizací voláním DbiBeginDelayedUpdates

  2. DBIResult DBIFN EXPORT DbiBeginDelayedUpdates(phDBICur phDbiCur);
    Velikost vyrovnávací paměti záznamů se může v režimu odložených aktualizací změnit. Je vhodné realokovat vyrovnávací paměti záznamů po instalaci vrstvy odložených aktualizací.
  3. Aplikování změn provedených na odložené aktualizace provedeme voláním DbiApplyDelayedUpdates

  4. DBIResult DBIFN EXPORT DbiApplyDelayedUpdates (hDBICur
              hDbiCur, DBIDelayedUpdCmd eUpdCmd);
    typedef enum
    {
       dbiDelayedUpdCommit = 0,
       dbiDelayedUpdCancel = 1
       dbiDelayedUpdCancelCurrent = 2
       dbiDelayedUpdPrepare = 3
    } DBIDelayedUpdCmd;
    Když použijeme na vložené, zrušené nebo modifikované záznamy, příkaz dbiDelayedUpdCancelCurrent nastavuje současný záznam na jeho původní stav.
  5. Po aplikování změn na databázi, uživatel může odstranit provedené změny z databáze. Nemáme ukončen režim odložených aktualizací. Po dokončení další dávky modifikací, může být voláno DbiApplyDelayedUpdates k aplikování těchto změn na databázi nebo provedení ROLLBACK.
  6. Ukončíme režim odložených aktualizací voláním DbiEndDelayedUpdates.

  7. DBIResult DBIFN EXPORT DbiEndDelayedUpdates(phDBICur phDbiCur);
Mechanismus zpětného volání je poskytnut, když zápis modifikovaných záznamů do databáze je neúspěšný. Protože aktualizace nejsou zaslány do připojené tabulky dokud nejsou detekovány žádné chyby před operací trvalého zápisu. Pokud chyba nastane v době COMMIT, pak uživatelé jsou dotázány s chybovou zprávou popisující chybu. Aplikace registruje funkce zpětného volání pro odložené aktualizace pomocí funkce DbiRegisterCallBack (ecbType pro toto zpětné volání je cbDELAYEDUPD) k oznámení chyb v průběhu COMMIT.
Deskriptor zpětného volání pro odložené aktualizace je:
// typ objektu odložené aktualizace
typedef enum
{
      delayupdNONE        = 0,
      delayupdMODIFY      = 1,
      delayupdINSERT      = 2,
      delayupdDELETE      = 3
} DelayUpdErrOpType;
// deskripror zpětného volání odložených změn.
typedef struct
{
      DBIResult           iErrCode;
      DelayUpdErrOpType   eDelayUpdErrOpType;
      // Velikost záznamu (fyzický záznam)
      UINT16              iRecBufSize;
      pBYTE               pNewRecBuf;
      pBYTE               pOldRecBuf;
} DELAYUPDCbDesc;
V deskriptoru zpětného volání eDelayUpdErrOpType indikuje typ operace (jako je vkládání, rušení nebo modifikace) a iErrCode indikuje jaký typ chyby nastal v průběhu operace eDelayUpdErrOpType. Klient musí alokovat dostatek paměti pro pNewRecBuf a pOldRecBuf. Každá vyrovnávací paměť záznamů musí mít alespoň velikost vyrovnávací paměti záznamu kurzoru odložených aktualizací. Nová (po aktualizací) a stará (před aktualizaci) výrovnávací paměť záznamu jsou vráceny klientovi prostřednictvím vyrovnávacích pamětí  pNewRecBuf a pOldRecBuf.
Klient může reagovat na zpětně volanou funkci následujícími návratovými kódy:
 
Návratový kód Výsledná akce
cbrABORT Celá operace COMMIT je zrušena. Je to implicitní návratový kód, pokud funkce zpětného volání není registrována.
cbrSKIP Chybná aktualizační operace je přeskočena a proces COMMIT pokračuje pro zbývající aktualizace.
cbrCONTINUE Chybná aktualizační operace je přeskočena a proces COMMIT pokračuje pro zbývající aktualizace.
cbrRETRY Chybná aktualizační operace bude zopakována.
cbrPARTIALASSIST Změny uživatele jsou drženy v cache. V tomto případě, uživatel aplikuje změny na původní tabulku.

 
14. API BDE I