Barvna shema: Riviera
Trenutno dejavna stran: start » sl » Dokumentacija » Integracija podatkov in dostop do podatkov » Gonilnik WKL OData ODBC » Koncepti gonilnika OData ODBC » Kako gonilnik prevaja stavke

Kako gonilnik prevaja stavke

graph TD
    A["Stavek SQL aplikacije (Access, ADO.NET, VBA)"] --> B{"Ali ga je mogoče izraziti kot zahtevo OData?"}
    B -->|da| C["Zahteva OData storitvi: $select, $filter, $orderby, $top, $skip, $count, $apply, POST/PATCH/DELETE"]
    B -->|ne| D{"Ali povezava ali storitev navaja naslov za lastne stavke?"}
    D -->|da| E["Nespremenjeno podatkovni zbirki (prepustna pot, z vezanimi vrednostmi)"]
    D -->|ne| F["Zavrnjeno s SQLSTATE 42000 in sporočilom, ki navaja razlog"]

Gonilnik sam ničesar ne izračuna. Vsak stavek se prevede v zahtevo OData, posreduje podatkovni zbirki ali zavrne – nikoli ne naloži cele tabele, da bi lokalno filtriral, združeval v skupine ali združeval tabele. To pojasnjuje, zakaj poizvedba v Accessu z eno storitvijo deluje, z drugo pa se konča z „ODBC–call failed“.

Ključne funkcije

  • Branje, filtriranje, razvrščanje in štetje na storitvi. Pogoji, razvrščanje, izbira stolpcev in COUNT(*) se storitvi pošljejo kot poizvedbene možnosti; prenesejo se samo ustrezne vrstice.
  • Urejanje kot pri tabeli SQL Serverja. INSERT, UPDATE in DELETE iz podatkovnega lista in obrazca postanejo POST, PATCH in DELETE, z zaznavanjem konfliktov pri pisanju prek If-Match.
  • Vsote in skupine brez prepustne poti, če storitev podpira združevanje v skupine.
  • Listanje z OFFSET … FETCH kot v SQL Serverju.
  • Dolgi pogoji v telesu namesto v naslovu.
  • Vse drugo se pošlje nespremenjeno podatkovni zbirki, če je to mogoče – sicer jasna zavrnitev namesto napačnega rezultata.

Osnovni pojmi

Prevedeno

Aplikacija pošljeGonilnik vpraša storitev
SELECT a, b FROM t WHERE x = ? ORDER BY aGET t?$select=a,b&$filter=x eq …&$orderby=a
… WHERE x LIKE '%Keller%'$filter=contains(x,'Keller') (prav tako x% → startswith, %x → endswith)
… WHERE Nr IN (?, ?, …)veriga pogojev or: Nr eq … or Nr eq …
SELECT COUNT(*) FROM t WHERE …GET t/$count?$filter=… – brez nalaganja vrstic
… ORDER BY a OFFSET 500 ROWS FETCH NEXT 200 ROWS ONLY$orderby=a&$skip=500&$top=200
SELECT g, SUM(x) FROM t GROUP BY g HAVING …$apply=groupby((g),aggregate(x with sum as …))&$filter=…, samo če storitev podpira $apply
SELECT … WHERE Ključ = ?$filter=Ključ eq … – branje vedno poteka prek množice, nikoli prek naslova ključa
INSERT INTO t …POST t
UPDATE t SET … WHERE Ključ = ? AND RazličicaVrstice = ?PATCH t(…) z If-Match
DELETE FROM t WHERE Ključ = ? AND RazličicaVrstice = ?DELETE t(…) z If-Match
UPDATE/DELETE tabele brez ključa prek vseh starih vrednostivezani dejanji UpdateByOriginal/DeleteByOriginal, če ju storitev podpira

Naslov, ki bi postal daljši od MAXURLLENGTH, se pošlje kot POST …/$query z možnostmi v telesu. Popolna pravila so v Podprti SQL: združevanje v skupine in povzemanje in Podprti SQL: branje po straneh z OFFSET/FETCH.

Posredovano

Kar ni mogoče prevesti – spoj dveh tabel, podpoizvedba, sprememba mnogih vrstic, stavek sheme, računanje med agregati –, gonilnik nespremenjeno pošlje na naslov za lastne stavke. Vezane vrednosti ostanejo vrednosti: iz označb mesta ? nastanejo poimenovani parametri. Stolpce rezultata opiše storitev, gonilnik tipov ne ugiba.

Naslov navede bodisi povezava (PASSTHROUGH) bodisi storitev v svojem dokumentu metapodatkov. Ali se stavek sme izvesti, odloči storitev, ne gonilnik; gonilnik ga ne preverja in ne razvršča. Zakaj, je pojasnjeno v Varnostni model in meje zaupanja; nastavitev pa v Nastavitev prepustnih poizvedb.

Izjema: stavke nad tabelami s predpono MSys – sistemskimi tabelami aplikacije, na primer poizvedba Accessa po MSysConf ob vsaki povezavi – gonilnik zavrne sam. V storitvi jih ni, Access pa pričakuje natanko ta odgovor.

Zavrnjeno

Brez naslova za lastne stavke gonilnik vse, česar ni mogoče prevesti, zavrne s SQLSTATE 42000. Access to prikaže kot napako 3146 „ODBC–call failed“ in poizvedbe nato ne izračuna sam – tudi ne vsot in spojev, ki bi jih pri lokalni tabeli zmogel sam. Glejte "ODBC--call failed" pri vsotah ali spojih.

Namesto približnega prevoda se zavrnejo – oziroma z naslovom za lastne stavke posredujejo – tudi: LIKE z _ ali razredom znakov ([a-c]), funkcije zunaj SUM, MIN, MAX, AVG, COUNT v združevanju v skupine, spreminjanje ali brisanje tabele brez različice vrstice prek starih vrednosti vseh stolpcev, če storitev zanjo ne deklarira ne lastnosti sočasnosti ne dejanj za tabele brez ključa. Razlog je vedno isti: tiho poenostavljen stavek bi vrnil drugačen rezultat, ki bi bil videti kot pravilen odgovor.

Transakcije

Vsak stavek je svoja zahteva storitvi. V transakcijo jih gonilnik združi samo, če storitev podpira transakcije: v tem primeru v $metadata navede naslov Store.Transactions (podatkovni prehod Wkl.Data.Gateway to stori).

StoritevSQL_TXN_CAPABLESamodejna potrditev izklopljena (BeginTrans, BeginTransaction)
s Store.TransactionsSQL_TC_ALL, izolacija READ COMMITTEDOb prvi zahtevi gonilnik odpre transakcijo na storitvi; vsaka nadaljnja zahteva povezave – branje, pisanje, lastni stavki – se izvede v njej in vidi njene lastne, še neshranjene spremembe. SQLEndTran jih shrani ali zavrže; prekinitev povezave jih zavrže
brezSQL_TC_NONEHYC00 namesto navidezno odprte transakcije

Access in DAO se samo po SQL_TXN_CAPABLE odločita, ali BeginTrans posredujeta gonilniku. Če storitev transakcij ne podpira, transakcijo obdržita zase: vsaka sprememba je takoj shranjena na storitvi, Rollback pa tam ničesar ne razveljavi – brez napake. Z njimi se koda VBA z BeginTrans/Rollback vede kot prek gonilnika SQL Serverja: Rollback razveljavi spremembe, nove zapise in poizvedbe za posodobitev, CommitTrans jih shrani, napaka enega stavka pa transakcijo pusti odprto.

Razlike od gonilnika SQL Serverja: transakcija na storitvi uporablja lastno povezavo; če je aplikacija nekaj časa ne uporablja, jo storitev razveljavi, CommitTrans pa v tem primeru javi 40001 – nič od tega ni shranjeno. Kako dolgo storitev čaka, določi sama; pri podatkovnem prehodu Wkl.Data.Gateway sta to privzeto dve minuti.

Pred uporabo preverite, ali transakcije delujejo

Če se aplikacija zanaša na Rollback – na primer postopek, ki skupaj ustvari glavo in postavke –, to preverite s storitvijo, na kateri naj bi se izvajala:

  1. Poizvedite po zmožnosti: v DAO CurrentDb.OpenRecordset("<povezana tabela>").Transactions (mora biti True), v ODBC SQLGetInfo(SQL_TXN_CAPABLE) (mora biti SQL_TC_ALL).
  2. Preizkusite na preizkusni vrstici: BeginTrans, spremenite vrstico, Rollback, znova preberite vrstico. Imeti mora staro vrednost.

Če je v 1. koraku False, Rollback na storitvi ničesar ne razveljavi, brez napake. Postopek, ki sme več zapisov shraniti samo skupaj, v tem primeru spada v proceduro podatkovne zbirke, ki jo aplikacija kliče prek prepustne poti, ali pa potrebuje storitev s transakcijami.

Kaj se zgodi pri napakah

PrimerRezultatKaj mora storiti aplikacija
Stavek v transakciji ne uspe (na primer kršen ključ)Stavek javi napako; transakcija ostane odprta, druge spremembe v njej ostanejo – kot prek gonilnika SQL Serverjasama odloči: Rollback ali shranjevanje drugih s CommitTrans
Storitev je transakcijo razveljavila (nedejavnost, neuporabna transakcija)CommitTrans javi 40001; nič ni shranjenopostopek začne znova
Povezava se prekine med CommitTrans08S01. Gonilnik zaključka ne ponovi: ni znano, ali je bilo shranjenoznova prebere zadevne zapise; če zaključek ni prispel do storitve, storitev transakcijo razveljavi po svojem času nedejavnosti
Povezava se prekine med Rollback08S01; nič se ne shrani, ker storitev odprto transakcijo razveljavi najpozneje po svojem času nedejavnostinič; zapisi so po izteku časa nedejavnosti spet prosti
Storitev ne podpira transakcijADO.NET: HYC00 pri BeginTransaction; DAO/Access: vsaka sprememba je takoj shranjena, Rollback ostane brez učinkaglejte preverjanje zgoraj

Sporočila podatkovne zbirke

Če podatkovna zbirka stavek zavrne in storitev pošlje njena sporočila (error.details s številko sporočila kot code, tako podatkovni prehod Wkl.Data.Gateway), jih gonilnik javi kot gonilnik SQL Serverja: en diagnostični zapis na sporočilo, številka sporočila kot izvorna številka napake in SQLSTATE, ki ga storitev navede zraven (23000 za kršen ključ, sklic ali obvezno vrednost, 22001 za predolgo vrednost, 01000 za spremljajoče opozorilo).

Aplikacijavidi
Access, okno s sporočilombesedilo prvega sporočila, za njim njegovo številko: … (#547)
VBA/DAODBEngine.Errors(0).Number = številka sporočila, .Description = besedilo; zadnji vnos je kot vedno napaka Accessa (3146)
ADO.NETOdbcException.Errors[i].NativeError in .SQLState

Koda, ki pri neposredni povezavi ravna glede na številko (If DBEngine.Errors(0).Number = 2627 Then), tako deluje nespremenjena. Besedilo storitev posreduje samo, če ne navaja ničesar, česar klicatelj ne sme videti; sicer je tam besedilo storitve, številka in SQLSTATE pa se kljub temu ujemata. Brez details gonilnik javi en sam zapis s statusom HTTP kot številko.

Zakaj tako: preučene alternative

Razdelitev na prevajanje, posredovanje in zavračanje je odločitev pri zasnovi. Tri alternative bi pravilnost, stroške ali varnost porazdelile bistveno drugače:

AlternativaKaj bi prineslaZakaj je zavržena
Lokalno računanje: gonilnik naloži vrstice in sam filtrira, združuje v skupine ali združuje tabeleVsaka poizvedba bi delovala, tudi s storitvijo brez združevanja v skupine in brez prepustne potiStroški rastejo s tabelo, ne z rezultatom, in ostanejo nevidni, dokler tabela ni velika. Poleg tega bi gonilnik računal po svojih pravilih za vrstni red razvrščanja, NULL in zaokroževanje, ne po pravilih podatkovne zbirke – rezultat bi brez opozorila odstopal
Samo posredovanje: vsak stavek se pošlje nespremenjen podatkovni zbirkiPolni jezik SQL podatkovne zbirke, brez pravil prevajanjaGonilnik bi bil vezan na storitev, ki ponuja tak naslov, in na njeno narečje SQL; vsak klicatelj bi potreboval pravico za izvajanje lastnih stavkov. Posredovan stavek se poleg tega prebere v celoti, brez naslednjih strani
Samo prevajanje, vse drugo zavrnitiNobene poti mimo pravil storitveAccess po zavrnitvi ne računa sam, tudi če SQLGetInfo zmožnost zanika. Spoji in vsote prek povezanih tabel ne bi v tem primeru nikoli uspele

Izbrana oblika združuje zadnji dve: kar je mogoče izraziti kot zahtevo OData, deluje z vsako storitvijo OData v4 in pod njenimi pravili za vsako tabelo; samo preostanek potrebuje naslov za lastne stavke. Njena cena: poizvedba, ki je ni mogoče izvesti po nobeni od obeh poti, vidno ne uspe, namesto da bi se izvajala počasi ali nenatančno. Prav tako je zavrženo približevanje posameznih sestavin, na primer LIKE 'a_c' kot contains; razlog je opisan v razdelku Zavrnjeno.

Sorodne teme

sl/wiki/data-conectivity/odata-odbc/concepts/how-the-driver-translates-statements.txt · Zadnja sprememba: uporabnika Wolfgang van der Stille