Sdílet prostřednictvím


Simulace pozičně umístěných příkazů Update a Delete

Pokud zdroj dat nepodporuje umístěné příkazy update a delete, ovladač je může simulovat. Například knihovna kurzorů ODBC simuluje umístěné příkazy update a delete. Obecná strategie pro simulaci pozičních příkazů UPDATE a DELETE je převádět poziční příkazy na prohledávané příkazy. To se provádí nahrazením klauzule WHERE CURRENT OF hledanou klauzulí WHERE , která identifikuje aktuální řádek.

Například vzhledem k tomu, že sloupec CustID jednoznačně identifikuje každý řádek v tabulce Customers, umístěný příkaz delete

DELETE FROM Customers WHERE CURRENT OF CustCursor  

může být převeden na

DELETE FROM Customers WHERE (CustID = ?)  

Ovladač může použít jeden z následujících identifikátorů řádků v klauzuli WHERE :

  • Sloupce, jejichž hodnoty slouží k jednoznačné identifikaci každého řádku v tabulce Například volání SQLSpecialColumns s SQL_BEST_ROWID vrátí optimální sloupec nebo sadu sloupců, které slouží k tomuto účelu.

  • Pseudosloupce poskytované některými zdroji dat pro účely jedinečné identifikace každého řádku. Můžou se také načíst voláním SQLSpecialColumns.

  • Jedinečný index, pokud je k dispozici.

  • Všechny sloupce v sadě výsledků

Přesně to, které sloupce má ovladač použít v klauzuli WHERE , závisí na ovladači. U některých zdrojů dat může být určení identifikátoru řádku nákladné. Je ale rychlejší spustit a zaručit, že simulovaný příkaz aktualizuje nebo odstraní maximálně jeden řádek. V závislosti na možnostech základního DBMS může být nastavení použití identifikátoru řádku nákladné. Je ale rychlejší spustit a zaručit, že simulovaný příkaz aktualizuje nebo odstraní jenom jeden řádek. Možnost použít všechny sloupce v sadě výsledků je obvykle mnohem jednodušší. Je ale pomalejší a pokud sloupce neidentifikují řádek jednoznačně, můžou vést k neúmyslné aktualizaci nebo odstranění řádků, zejména pokud seznam výběru sady výsledků neobsahuje všechny sloupce, které existují v podkladové tabulce.

V závislosti na tom, které z předchozích strategií ovladač podporuje, může aplikace zvolit, jakou strategii má ovladač použít s atributem příkazu SQL_ATTR_SIMULATE_CURSOR. I když může aplikace riskovat neúmyslnou aktualizaci nebo odstranění řádku, aplikace může toto riziko odebrat tím, že zajistí, aby sloupce v sadě výsledků jednoznačně identifikovaly každý řádek v sadě výsledků. Tím ušetříte řidiči námahu, protože to nemusí dělat.

Pokud se ovladač rozhodne použít identifikátor řádku, zachytí příkaz SELECT FOR UPDATE , který vytvoří sadu výsledků. Pokud sloupce v seznamu výběrů efektivně neidentifikují řádek, ovladač přidá potřebné sloupce na konec seznamu výběru. Některé zdroje dat mají jeden sloupec, který vždy jednoznačně identifikuje řádek, například sloupec ROWID v Oracle; pokud je takový sloupec k dispozici, ovladač ho použije. V opačném případě ovladač volá SQLSpecialColumns pro každou tabulku v klauzuli FROM k načtení seznamu sloupců, které jednoznačně identifikují každý řádek. Běžné omezení, které je výsledkem této techniky, je, že simulace kurzoru selže, pokud je v klauzuli FROM více než jedna tabulka.

Bez ohledu na to, jak ovladač identifikuje řádky, obvykle před odesláním do zdroje dat odstraní klauzuli FOR UPDATE z klauzule SELECT FOR UPDATE . Klauzule FOR UPDATE OF se používá pouze s umístěnými příkazy update a delete. Zdroje dat, které nepodporují umístěné příkazy update a delete, je obecně nepodporují.

Když aplikace odešle poziční příkaz update nebo delete k provedení, ovladač nahradí klauzuli WHERE CURRENT OF klauzulí WHERE obsahující identifikátor řádku. Hodnoty těchto sloupců se načítají z mezipaměti udržované ovladačem pro každý sloupec, který používá v klauzuli WHERE . Jakmile ovladač nahradí klauzuli WHERE , odešle příkaz do zdroje dat ke spuštění.

Předpokládejme například, že aplikace odešle následující příkaz k vytvoření sady výsledků:

SELECT Name, Address, Phone FROM Customers FOR UPDATE OF Phone, Address  

Pokud aplikace nastavila SQL_ATTR_SIMULATE_CURSOR požadovat záruku jedinečnosti a pokud zdroj dat neposkytuje pseudosloupec, který vždy jednoznačně identifikuje řádek, ovladač volá SQLSpecialColumns pro tabulku Customers, zjistí, že CustID je klíčem k tabulce Customers a přidá ho do seznamu výběrů. a odstraní klauzuli FOR UPDATE OF :

SELECT Name, Address, Phone, CustID FROM Customers  

Pokud aplikace nepožadovala záruku jedinečnosti, ovladač odstraní pouze klauzuli FOR UPDATE OF :

SELECT Name, Address, Phone FROM Customers  

Předpokládejme, že aplikace prochází sadu výsledků a odešle následující umístěný aktualizační příkaz pro spuštění, kde Cust je název kurzoru nad sadou výsledků:

UPDATE Customers SET Address = ?, Phone = ? WHERE CURRENT OF Cust  

Pokud aplikace nepožadovala záruku jedinečnosti, ovladač nahradí klauzuli WHERE a vytvoří vazbu parametru CustID na proměnnou v mezipaměti:

UPDATE Customers SET Address = ?, Phone = ? WHERE (CustID = ?)  

Pokud aplikace nepožadovala záruku jedinečnosti, ovladač nahradí klauzuli WHERE a vytvoří vazbu parametrů Name, Address a Phone v této klauzuli na proměnné v mezipaměti:

UPDATE Customers SET Address = ?, Phone = ?  
   WHERE (Name = ?) AND (Address = ?) AND (Phone = ?)