HTTP: specifikacija vmesnika
Lastni vmesnik prehoda pod /api/v1/ – branje, pisanje, klicanje procedur, izvajanje lastnih
stavkov – za programe, ki ne uporabljajo OData. Odjemalci z OData v4 (Access prek gonilnika,
Excel, Power BI) uporabljajo vmesnik OData.
Sintaksa
GET /api/v1/cf/{alias}/{tables|views|functions}/{name}.json
POST /api/v1/cf/{alias}/procedures/{name}.json telo JSON z imenovanimi argumenti
POST /api/v1/cf/{alias}/sql.json telo: lastni stavek (treba odobriti)
GET /api/v1/cf/{alias}/tables/{name}.json?{ključ}={vrednost} branje enega zapisa
POST /api/v1/cf/{alias}/tables/{name}.json telo: polja ustvarjanje → 201 + zapis
PATCH /api/v1/cf/{alias}/tables/{name}.json?{ključ}={vrednost} telo: polja spreminjanje → 200 + zapis
DELETE /api/v1/cf/{alias}/tables/{name}.json?{ključ}={vrednost} brisanje → 204
Brez prijave, za nadzor delovanja in prenos namestitvenih paketov:
GET /health/live proces živi (200, besedilo "Healthy")
GET /health/ready 200; "Healthy" z vsaj enim aliasom, sicer "Degraded" (tudi takrat 200)
GET /api/v1/health {"status":"ok","configuredAliases":<število>}
GET /download/ namestitveni paketi (glejte spodaj)
S prijavo Windows, za zaganjalnik WKL:
GET /schema-state/{alias}/{izdelek} stanje sheme podatkovne zbirke z različicami (glejte spodaj)
Parametri
Končnica določa predstavitev, .json ali .xml, na vsakem od teh naslovov, enako za uspešen odgovor
in za napako. Glejte Predstavitve.
Prijava je mogoča z vsakim postopkom, ki ga konfiguracija odobri: ključ storitve v glavi X-Api-Key,
osebni ključ (v isti glavi ali kot geslo HTTP Basic), račun Windows (Negotiate) ali prijava SQL Server
(HTTP Basic). Vsi postopki, njihovi odgovori in 2FA so opisani v HTTP: prijava;
za to specifikacijo vmesnika veljajo nespremenjeno.
Pisanje v tabele
Pisanje je tako dinamično kot branje: metoda, tabela, ključ in polja pridejo iz zahteve, SQL ustvari prehod. Klicatelj ne pošilja SQL: določi le zapis (s ključem) in vrednosti (s polji), nikoli stavka, pogoja ali stolpca, ki ga katalog ne pozna.
PATCH /api/v1/cf/fachdaten/tables/APPARAT.json?nummer=4711
X-Api-Key: …
If-Match: "AAAAAAAQgpE="
Content-Type: application/json
{ "benennung": "Kühler Nord", "preis": 12.50 }
Načela in utemeljitev: Pisanje in konflikti pri pisanju.
| Pravilo | Zakaj |
|---|---|
PATCH nastavi le navedena polja | Ostala polja obdržijo svojo vrednost; tako nihče ne ponastavi petdesetih polj na stanje starejše kopije |
PUT ni ponujen (405) | „Nadomesti zapis“ bi moral izprazniti vsak nenavedeni stolpec |
| Ključa ni mogoče spremeniti | Zapis ne bi bil več dosegljiv pod naslovom, prek katerega je bil spremenjen |
| V identitetne in izračunane stolpce ter stolpce različice ni mogoče pisati | Te vrednosti nastavi podatkovna zbirka |
| Neznana ali dvakrat zapisana polja se zavrnejo | Katera od dveh vrednosti bi obveljala, bi bilo odvisno od vrstnega reda v telesu |
| Pri ustvarjanju morajo biti navedena vsa obvezna polja in ključ | Razen ključa, ki ga dodeli podatkovna zbirka – kot identiteto ali s privzeto vrednostjo (NEWSEQUENTIALID(), NEWID(), zaporedje); dodeljeno vrednost stavek prebere ob vstavljanju (OUTPUT … INTO, tudi pri tabelah s sprožilci), z njo se nato prebere shranjeni zapis |
Kako se vežejo vrednosti: Časovne točke, števila in imena.
| Odgovor | Pomen |
|---|---|
201 / 200 + zapis | ustvarjeno / spremenjeno; zapis je shranjeno stanje |
204 | izbrisano |
400 | ključ nepopoln, polje neznano ali vanj ni mogoče pisati, vrednost se ne ujema s tipom |
404 | ni zapisa s tem ključem |
409 | ključ pri ustvarjanju že dodeljen |
412 | različica vrstice zastarela |
422 | podatkovna zbirka je zahtevo zavrnila (obvezna vrednost, tuji ključ, pogoj preverjanja); sporočila SQL Serverja so v details (glejte „Sporočila SQL Serverja“ pri obliki napak); če sprožilec sproži lastno sporočilo, je njegovo besedilo v message (glejte „Izjema: sporočila aplikacije“) |
Za pisanje klicatelj potrebuje pravilo z vrsto vira tables in metodami HTTP POST, PATCH,
DELETE. Oznaka samo za branje vse tri onemogoči.
Poizvedbene možnosti pri branju: $select, $filter, $orderby, $top, $skip, $count. Vse se
prevede v SQL in ovrednoti v podatkovni zbirki.
Kaj sprejme $filter
| Sestavni del | Sprejeti zapisi |
|---|---|
| Primerjave | eq ne gt ge lt le, preverjanje manjkajoče vrednosti z eq null / ne null |
| Polje proti polju | ParentId eq Id, Stufe lt Grenze: desno ime polja namesto vrednosti; obe polji morata pripadati množici, polje brez vrednosti ne ustreza ne primerjavi ne njeni negaciji. Besedilo proti številu SQL Server zavrne (422) – od specifikacije vmesnika 0.4.0 (GatewayFilter.FieldComparison) |
| Povezave | and, or, not, oklepaji |
| Iskanje besedila | startswith(feld,'x'), endswith(feld,'x'), contains(feld,'x'), substringof('x',feld) |
| Števila | 5, 12.5, z oznako tipa 5L, 12.5m, 12.5f, 12.5d |
| Časovne točke | datetime'2023-01-01T00:00:00', datetimeoffset'…' ter brez imena tipa 2023-01-01T00:00:00Z |
Identifikatorji (uniqueidentifier) | guid'6f9619ff-8b86-d011-b42d-00cf4fc964ff' ter brez imena tipa 6f9619ff-8b86-d011-b42d-00cf4fc964ff (tako jih zapiše gonilnik ODBC) |
| Drugi tipi | time'…', binary'…' |
Sprejeti so zapisi obeh različic protokola, ker odjemalci ne pripadajo isti generaciji: substringof
in datetime'…' izhajata iz starejše različice, contains, časovna točka in identifikator brez
imena tipa pa iz novejše. Kateri zapis prispe, določi odjemalec.
Zavrnjen literal je dražji, kot se zdi. Odjemalec za preglednice ali poročila
400ne sporoči naprej – pogoj opusti in namesto tega prebere celoten objekt. Iz ciljne poizvedbe tako nastane branje celotne tabele, ki se pri velikih tabelah lahko prekine. Zato so literali protokola del specifikacije vmesnika in ne zgolj udobje.
Katere poizvedbene možnosti so podprte
Podprte: $select, $filter, $orderby, $top, $skip, $count, $inlinecount, $format (samo json).
Skupno število je mogoče zahtevati v obeh zapisih – $count=true in $inlinecount=allpages –,
ker ga starejša in novejša različica protokola imenujeta različno, odjemalec pa odloči, kateri pride.
Zavrnjeno z 400:
| Zavrnjeno | Sporočilo |
|---|---|
$expand, $apply, $search, $compute, $skiptoken, $levels, $ref, $value, $id | „wird von diesem Dienst nicht ausgeliefert“ (ta prehod tega ne vrača) ($skiptoken in $apply sprejme samo vmesnik OData, glejte tam razdelka o naslednjih straneh in združevanju) |
vsaka druga možnost z $ | „ist keine bekannte Abfrageoption“ (ni znana poizvedbena možnost) |
vrednost, ki ni niti true niti false ($count=yes) | „erwartet 'true' oder 'false'“ (pričakuje 'true' ali 'false') |
druga predstavitev kot JSON ($format=xml) | „wird nicht ausgeliefert“ (se ne vrača) |
Prezrta možnost je hujša od zavrnjene. Možnost pove, katere vrstice ali stolpci so želeni; če jo prezremo, ne nastane napaka, temveč drugačen rezultat, ki je videti kot pravilen odgovor. Brez tega preverjanja bi zahteva z
$fillter=Typ eq 'S'– ena črka preveč – dobila odgovor200s celotnim objektom namesto iskanih vrstic, in nič v odgovoru tega ne bi razkrilo.
Razlikovanje med „se ne vrača“ in „neznano“ je namerno: kdor pošlje $expand, je zapisal nekaj
pravilnega, kar tu ni podprto; kdor pošlje $fillter, se je zatipkal. Primera zahtevata različen
popravek, skupno sporočilo pa bi prvega poslalo iskat tipkarsko napako, ki je ni.
Oblika odgovora
{ "data": [ … ], "rowCount": 100, "count": 100, "window": 100, "totalCount": 250, "nextLink": "/api/v1/cf/fachdaten/views/liste.json?$skip=100&wkl-page=…", "executionTimeMs": 0 }
| Polje | Pomen |
|---|---|
rowCount | Vrstice v tem odgovoru. Vedno prisotno, nikoli negativno |
count | Enako kot rowCount. Starejši zapis predhodnika prehoda; ostane, ker ga obstoječi klicatelji berejo |
window | Velikost okna, s katero je bilo dejansko prebrano. Pri klicu procedure ni prisotno |
totalCount | Skupno število vrstic, ki ustrezajo filtru. Prisotno samo pri $count=true |
affectedRowCount | Vrstice, ki jih je spremenil klic procedure – samo če ni vrnil rezultata |
truncated | Prisotno samo, če je učinkovala omejitev števila vrstic |
nextLink | Povezava na naslednje okno, absolutna na ravni poti. Prisotno samo, če je prehod okno izbral in napolnil – na koncu polje manjka |
windowinnextLinksta dopolnitvi glede na starejše različice. Brezwindowklicatelj polnega okna ne more razlikovati od kratkega – in prav po tem klicatelj brez$countprepozna, da je prišel do konca. Zahtevana velikost za to ne zadošča: prehod jo omeji na nastavljeno zgornjo mejo, kdor pa je ne navede, dobi nastavljeno privzeto vrednost, ki je ne pozna. Odjemalec, ki polja ne pozna, ga prezre.
nextLinkpove isto v obliki, ki jo orodje razume tudi brez poznavanja te specifikacije vmesnika: povezavi sledi, dokler je v odgovoru.windowje dogovor, ki ga ovrednoti le posebej za to napisan klicatelj – vsak drug se po prvem oknu ustavi in ga ima za celoten rezultat.
Kdaj je ponujena povezava na naslednjo stran
| Zahteva | Odgovor |
|---|---|
brez $top, okno polno | povezava s $skip + velikost okna, brez $top |
$top večji od MaxTop, okno polno | povezava s preostankom kot $top – kdor zahteva 25.000, dobi natanko 25.000, razdeljenih na več oken |
$top ni večji od MaxTop | brez povezave – klicatelj je dobil, kar je zahteval |
| okno kratko ali prazno | brez povezave – rezultata je konec |
Vse druge možnosti – filter, projekcijo, razvrščanje, argumente funkcij – povezava prevzame
nespremenjene, da je vsako okno okno istega rezultata. Odpade le štetje ($count,
$inlinecount): za vsa okna istega branja je enako, ponavljanje za vsako okno pa bi pomenilo
ponavljanje najdražjega dela za že znan odgovor. Polno okno ne dokazuje, da obstajajo nadaljnje vrstice; če se rezultat
konča natanko na njegovem robu, povezava vodi do praznega okna. To je pravilen odgovor in cenejši kot
štetje pri vsakem branju.
Povezava je absolutna na ravni poti (/api/v1/cf/…?…) in ne navaja gostitelja: za posredniškim
strežnikom gostitelj, ki ga vidi ta proces, ni nujno tisti, ki ga je uporabil klicatelj.
totalCountmanjka, če nihče ni štel. To ni isto kot0. Kdor manjkajočo vrednost obravnava kot ničlo, seznamu sporoči, da ni ničesar za nalaganje – čeprav podatki dokazano obstajajo in brez kakršnega koli sporočila o napaki.
Oblika napak
Navedba „od specifikacije vmesnika 0.x“ pomeni različico paketa specifikacije vmesnika Wkl.Data.Gateway.Contracts, od
katere je vrsta napake ali polje znano; brez podatka velja od 0.1.0. Program, ki ostaja pri
starejši različici, novejše vrste bere z njihovo statusno kodo, kot je spodaj opisano za vsako vrsto.
{ "error": { "code": "NOT_FOUND", "message": "…", "correlationId": "…" } }
Kode: BAD_REQUEST (400), UNAUTHENTICATED (401), FORBIDDEN (403), NOT_FOUND (404),
CONFLICT (409), PRECONDITION_FAILED (412), LIMIT_EXCEEDED (429), DATABASE_REJECTED
(422), UNAVAILABLE (503), DATABASE_UNREADABLE (503), TIMEOUT (504), INTERNAL (500).
UNAVAILABLE ne pomeni le nedosegljive podatkovne zbirke, temveč vsako nepričakovano napako v
prehodu. Po pisalni zahtevi (POST, PATCH, DELETE, zaključek transakcije) 503 zato pomeni:
ni znano, ali je bilo zapisano. Odgovor 5xx se za Idempotency-Key ne shrani; ponovitev lahko
zato zapiše še enkrat. Zapis prej znova preberite.
LIMIT_EXCEEDED pomeni vsako omejitev prehoda: zahteve na obdobje, neuspele poskuse, število vezanih
vrednosti, velikost telesa (Limits:MaxBodyBytes), odprte transakcije. Za preveliko telo specifikacija vmesnika s
tem odstopa od RFC 9110, razdelek 15.5.14,
ki predvideva 413 Content Too Large: klicatelj naj vse omejitve prepozna po eni sami kodi. Ali pomaga
čakanje (omejevanje hitrosti) ali le manjša zahteva (telo, vrednosti), pove message.
TIMEOUT (od specifikacije vmesnika 0.3.0; prej UNAVAILABLE) pomeni: stavek se je izvajal in prekoračil
Limits:QueryTimeoutSeconds. Podatkovna zbirka je bila dosegljiva; gonilnik podatkovne zbirke to sporoči
kot prekoračitev časa (SQLSTATE HYT00), ne kot izgubljeno povezavo. TIMEOUT in UNAVAILABLE
veljata za začasni napaki (IsTransient).
DATABASE_UNREADABLE (od specifikacije vmesnika 0.6.0; prej UNAVAILABLE) pomeni: SQL Server je bil dosegljiv,
podatkovne zbirke aliasa pa ne more brati. Datotek podatkovne zbirke ni mogoče brati (823, 824, 605)
ali pa je podatkovna zbirka brez povezave (942), označena kot sumljiva (926), njenih datotek ni
mogoče odpreti (945), se še obnavlja (922) ali manjka njen dnevnik (9001). message navede
alias, na primer „Die Datenbank der Datenquelle 'lager' ist auf dem Server derzeit nicht lesbar. Bitte
den Betreuer verstaendigen.“ (Podatkovne zbirke vira podatkov 'lager' na strežniku trenutno ni mogoče
brati. Obvestite skrbnika.); imena datotek in številka so le v dnevniku, details manjka. Ni
začasna napaka: ponovitev pomaga šele, ko nekdo ukrepa na strežniku. Klicatelj, ki kode ne pozna,
prebere statusno kodo 503 in jo obravnava kot UNAVAILABLE. Odjemalec .NET Wkl.Data.Gateway.Client
jo od različice 0.2.0 sporoči kot GatewayProblemKind.DatabaseUnreadable (ni začasna); različica
0.1.0 kode ne pozna in sporoči GatewayProblemKind.Unavailable, torej „začasno“. 503 v nobenem
primeru ne pomeni „ni podatkov“. Nasprotno pa odsotnost te kode ne dokazuje, da je podatkovna zbirka berljiva: koda
velja le za zgoraj navedene številke napak; napaka pri branju iz drugega razloga pride kot
UNAVAILABLE.
Po kratkotrajni izgubi pogona z datotekami podatkovne zbirke stanje ostane tako, dokler se storitev „SQL Server“ na strežniku podatkovne zbirke ne zažene znova; stavki, katerih strani so še v pomnilniku SQL Serverja, se medtem še naprej uspešno izvajajo.
Za neznan vir in za vir, ki ga klicatelj ne sme brati, je odgovor v obeh primerih NOT_FOUND.
Izjemi: za objekt, ki ga klicatelj sme brati, ne sme pa spreminjati, je odgovor FORBIDDEN; preverjeni
stavek tako za neznane kot za skrite objekte odgovori s FORBIDDEN. Razlikovanje bi prehod spremenilo v imenik:
klicatelj bi s primerjanjem odgovorov lahko izvedel, kateri objekti obstajajo.
Odgovor z napako nikoli ne vsebuje imena podatkovne zbirke, niza povezave, besedila stavka ali
imena objekta, ki ga klicatelj ne sme videti. Ti podatki so v dnevniku, kjer jih najdete po
correlationId.
Sporočila SQL Serverja (details, od specifikacije vmesnika 0.5.0). Če podatkovna zbirka zavrne stavek, odgovor
vsebuje sporočila SQL Serverja v vrstnem redu, v katerem jih ta sporoči – tako kot pri neposredni
povezavi prek gonilnika SQL Serverja –, da lahko koda ravna glede na številko (na primer 2627 „ključ že
dodeljen“ v primerjavi s 547 „kršen sklic“):
{ "error": { "code": "DATABASE_REJECTED", "message": "Der Vorgang wurde von der Datenbank abgelehnt.",
"correlationId": "…",
"details": [ { "code": "547", "sqlState": "23000", "severity": 16, "released": true,
"message": "Die INSERT-Anweisung steht in Konflikt mit der CHECK-Einschränkung …" } ] } }
| Polje | Vsebina |
|---|---|
code | Številka sporočila SQL Serverja kot besedilo (oblika OData za details) |
sqlState | SQLSTATE, ki ga gonilnik SQL Serverja sporoči za to številko: 23000 omejitev, ključ, obvezna vrednost; 22001 vrednost predolga; 22018 pretvorba; 22007/22008 datum ali čas; 22003 prekoračitev; 22012 deljenje z ničlo; 42S02/42S22 objekt oz. stolpec neznan; 25000 stanje transakcije; 40001 smrtni objem; 01000 obvestilo; sicer 42000 |
severity | Resnost: do 10 obvestilo, ki spremlja zavrnitev, od 11 napaka |
released | true: message je besedilo SQL Serverja. false: besedilo navaja objekt, ki ga klicatelj ne sme videti; message je takrat besedilo prehoda, številka in SQLSTATE pa sta kljub temu pravilni |
message | Besedilo, kot je opisano zgoraj |
details vsebuje največ deset sporočil. Številko klicatelj prejme za vsako od njih, besedilo pa le, če
ne vsebuje imena, ki ga klicatelj ne sme videti: nobene tabele, pogleda, rutine, omejitve, sprožilca in
indeksa objekta, ki ga njegova pravila ne dosežejo, ne imena prijave aliasa in ne imena strežnika. Ime
se preveri kot celotna beseda, ne glede na narekovaje; tako preverjanje deluje tudi v nemških
sporočilih, ki imena navajajo brez narekovajev („in der lager-Datenbank“ (v podatkovni zbirki lager)).
Ime podatkovne zbirke se nadomesti z aliasom. Če je skrito ime po naključju navadna beseda,
prehod zadrži tudi neškodljivo besedilo; številka je kljub temu posredovana.
Sporočila z vrednostjo. Napake pretvorbe (245, 8114, datumske vrednosti 241 in 242), podvojen ključ
(2627, 2601) in odrezana vrednost (2628, 8152) navajajo vrednost („… beim Konvertieren des Werts 'X' …“
(… pri pretvorbi vrednosti 'X' …), „Der doppelte Schlüsselwert ist (X)“ (Podvojena vrednost ključa je
(X))). Ali je X vnesel klicatelj ali je bila prebrana iz podatkov, od zunaj ni mogoče ugotoviti: filter
klicatelja, lastni stavek (INSERT … SELECT, UPDATE … FROM, MERGE), procedura ali sprožilec lahko
prebrano vrednost namerno spravi v enolični ali prekratek stolpec. Če se stavek izvaja s prijavo aliasa,
prehod besedilo teh sporočil zato vedno zadrži (released false); številka, SQLSTATE in statusna
koda (409 pri že dodeljenem ključu) so posredovani. Razlog: če podatkovna zbirka vrstice skriva po osebi (varnost
na ravni vrstic prek SESSION_CONTEXT, ki ga nastavi prehod), lahko SQL Server takšne izraze
ovrednoti pred varnostnim pogojem ali ob njem, besedilo pa bi izdalo vrednost iz skrite vrstice; pri
prijavi aliasa je preverjanje prehoda edina zaščita. Če se stavek izvaja v imenu osebe (menjava identitete ali
lastna prijava SQL Server), SQL Server sam odloči, kaj sme brati, besedilo pa pride kot prek
neposredne povezave. Pravilo je vezano na identiteto, ne na obliko stavka.
details manjka pri izgubljeni povezavi (503), neberljivi podatkovni zbirki (503
DATABASE_UNREADABLE) in prekoračitvi časa (504): to so podatki o povezavi, ne odgovori podatkovne
zbirke na stavek. message in statusna koda ostaneta nespremenjena.
Izjema: sporočila aplikacije. Če aplikacija v podatkovni zbirki sama sproži sporočilo – THROW z
lastno številko ali RAISERROR z besedilom, torej številka napake od 50000 naprej in resnost od 11 do
16 –, je njegovo besedilo v odgovoru kot message (422 DATABASE_REJECTED), ne glede na pot: klic
procedure, pisanje v tabele (tudi iz sprožilca), OData in prepustni stavek. Takšno sporočilo je napisano
za človeka, ki je dejanje sprožil, in neposredna povezava bi mu ga prav tako prikazala. Kaj sporočilo navaja,
odloči njegov avtor. Sporočila samega SQL Serverja (številka pod 50000) so samo v details;
message takrat ostane besedilo prehoda.
Klicanje procedur
Shranjena procedura se pokliče s POST na procedures/{name}; telo je objekt JSON z argumenti po
imenih.
POST /api/v1/cf/fachdaten/procedures/auftrag_anlegen.json
X-Api-Key: …
Idempotency-Key: 6c1e0c7a-…
Content-Type: application/json
{ "kunde_id": 4711, "betreff": "Kühler Nord", "stand": "2026-10-10T17:00:00.123+02:00", "notiz": null }
Prehod iz tega izvede SET XACT_ABORT ON; EXEC [schema].[auftrag_anlegen] @kunde_id = @p0, ….
| Pravilo | Zakaj |
|---|---|
Imena argumentov brez @; ime z @ se zavrne kot neveljaven identifikator (400) | Predpono nastavi prehod. Poslana predpona bi dala @@name, ime samo iz @ pa parameter brez imena – obe napaki bi se pokazali šele v podatkovni zbirki, s sporočilom o proceduri namesto o zahtevi |
| Klic po imenih; izpuščen argument prevzame privzeto vrednost procedure | Klic po položaju ne more preskočiti neobveznega parametra |
JSON null postane NULL | Manjkajoča vrednost se mora razlikovati od praznega besedila; kot poizvedbeni argument bi neobvezno besedilo prišlo kot '' in prepisalo vrednost, ki naj bi ostala |
| Procedura brez parametrov se pokliče brez telesa | To je navaden klic, ne napaka |
Objekt ali seznam kot vrednost se zavrne (400) | Noben parameter procedure ga ne sprejme; če bi ga pretvorili v besedilo, bi procedura dobila nekaj, česar ni nikoli deklarirala |
Okoli klica ni transakcije prehoda; pred njim SET XACT_ABORT ON | Procedura vodi svojo transakcijo. Zunanja transakcija bi gnezdila: notranji ROLLBACK bi zavrgel tudi zunanjo, notranji COMMIT bi le zmanjšal števec. XACT_ABORT ob napaki med izvajanjem razveljavi spremembe, namesto da bi odprto transakcijo z njenimi zaklepi vrnil v bazen povezav |
Klic je natanko en EXEC | Kar potrebuje več korakov, je procedura z več koraki v eni transakciji; dva zaporedna klica bi ob napaki vmes pustila polovično stanje |
Preslikava tipov argumentov. Vrednosti se vežejo brez podatka o tipu; SQL Server vrednost pretvori v tip parametra.
| Vrednost JSON | Vezano kot |
|---|---|
| Besedilo | nvarchar |
Celo število (4711) | bigint |
Decimalno število brez eksponenta (12.50) | decimal, natančno |
Število z eksponentom (1E-300) | float |
true / false | bit |
null | NULL |
Posledica za časovne točke: datuma JSON ni. Časovna točka se prenese kot besedilo, na primer ISO 8601
(2026-10-10T17:00:00.123+02:00), SQL Server pa jo pretvori v tip parametra – tudi v parameter
varchar, ki ga procedura pretvori sama (CONVERT(…, 127)).
Oblika odgovora.
{ "data": [ { "ergebnis": "angelegt", "auftrag_id": 815, "stand": "2026-10-10T17:00:00.123+02:00" } ], "rowCount": 1, "count": 1, "executionTimeMs": 12 }
| Polje | Pomen |
|---|---|
data | Prvi niz rezultatov procedure kot seznam objektov (ime stolpca → vrednost). Nadaljnji nizi rezultatov se ne berejo. Brez niza rezultatov prazen seznam |
rowCount, count | Vrstice v data |
affectedRowCount | Samo če procedura ni vrnila niza rezultatov: število spremenjenih vrstic; data je takrat prazen seznam |
truncated | Učinkovala je omejitev števila vrstic aliasa |
executionTimeMs | Čas izvajanja v prehodu |
Okna in nextLink ni: procedura vrne niz rezultatov, za katerega je napisana, klicatelj pa ne more
zahtevati njegovega dela. Vrednosti niza rezultatov so v isti obliki kot pri branju; datetimeoffset
s svojim zamikom.
Na tej poti ni parametrov OUTPUT in ni vrednosti RETURN. Ta naslov ne bere ne enega ne drugega
in bere le prvi niz rezultatov. Kar naj klicatelj izve – dodeljeni identifikator, novo stanje, oznako
rezultata –, procedura tu vrne kot niz rezultatov (SELECT … AS ergebnis, … AS id). Če potrebujete
izhodne parametre, vrednost RETURN ali vse nize rezultatov, proceduro pokličite kot stavek
(EXEC @rueckgabe = …), glejte
Izhodni parametri, več nizov rezultatov, opisovanje.
Napake.
| Vzrok v proceduri | Odgovor |
|---|---|
THROW z lastno številko, RAISERROR z besedilom, od resnosti 11 | 422 DATABASE_REJECTED, message je besedilo sporočila |
| Napaka samega SQL Serverja (na primer deljenje z ničlo, tuji ključ) | 422 DATABASE_REJECTED, besedilo „Der Vorgang wurde von der Datenbank abgelehnt.“ (Podatkovna zbirka je dejanje zavrnila.) |
RAISERROR do resnosti 10 (obvestilo) | Ni napaka: 200 z rezultatom; besedilo obvestila se izgubi |
Kršen primarni ključ ali enolični indeks (2627, 2601) | 409 CONFLICT |
Prekoračena časovna omejitev prehoda (Limits:QueryTimeoutSeconds) | 504 TIMEOUT |
| Podatkovna zbirka ni dosegljiva | 503 UNAVAILABLE |
Podatkovne zbirke na strežniku ni mogoče brati (823, brez povezave, sumljiva) | 503 DATABASE_UNREADABLE |
Manjkajoča pravica (229, 230, 262, 297, 300, 916) | 403 FORBIDDEN, če se stavek izvaja v imenu osebe (menjava identitete ali prijava SQL Server); sicer 422 – takrat manjka pravica prijave aliasa, kar je vrzel v nastavitvi, ne pri klicatelju |
Od specifikacije vmesnika 0.5.0 so številka, SQLSTATE in resnost vsakega sporočila v details, besedilo le, če ga
prehod sprosti (glejte Oblika napak); prej je bilo v message le besedilo sporočila
aplikacije. Če naj klicatelj glede na razlog ravna različno, je razlog vseeno bolje vrniti kot vrstico
rezultata (ergebnis = 'gesperrt'): številko aplikacije od 50000 naprej je mogoče prosto izbrati za
vsak razlog, a je le dogovor med proceduro in klicateljem. Sporočilo pod resnostjo 11 pa je obvestilo,
ne napaka: ničesar ne prekine in se v odgovoru nikjer ne pojavi.
Pravice. Klicatelj potrebuje pravilo z vrsto vira procedures in metodo HTTP POST; oznaka samo
za branje klic onemogoči, ker prehod ne more vedeti, ali procedura piše. Za proceduro, ki je katalog
aliasa ne pozna ali je klicatelj ne sme klicati, je odgovor 404. Ponovitve po prekinitvi povezave:
Idempotency-Key velja tudi tukaj, glejte
Ponovljene pisalne zahteve.
Dolge poizvedbe: možnosti v telesu
Poizvedbene možnosti bralne zahteve so v naslovu, dolžino naslova pa omeji gostitelj pred prehodom:
IIS privzeto sprejme največ 2.048 bajtov poizvedbenega niza
(requestFiltering/requestLimits/@maxQueryString, Microsoft:
Request Limits),
Kestrel 8 KB vrstice zahteve (KestrelServerLimits.MaxRequestLineSize). Predloga IIS namestitvenega
paketa mejo dvigne na 8.192 znakov. Bralna zahteva lahko zato svoje možnosti pošlje tudi v telesu – v
dveh oblikah, na obeh vmesnikih:
POST /odata/v4/fachdaten/dbo/Artikel/$query Content-Type: text/plain POST /odata/v4/fachdaten/dbo/Artikel/$count/$query POST /api/v1/cf/fachdaten/tables/artikel.json/$query QUERY /odata/v4/fachdaten/dbo/Artikel (enako na ostalih naslovih) $filter=Nummer%20eq%201%20or%20Nummer%20eq%202&$select=Nummer,Bezeichnung&$count=true
Telo je natanko besedilo, ki bi sicer stalo za ?. POST …/$query je oblika, ki jo za to
predvideva OData 4.01 (OData Version 4.01 Part 1: Protocol,
razdelek „Passing Query Options in the Request Body“), in jo prepusti vsak posredniški strežnik, ki
prepušča POST. QUERY je metoda za varne bralne zahteve s telesom iz osnutka IETF „The HTTP QUERY Method“
(draft-ietf-httpbis-safe-method-w-body); ker gre za osnutek, jo prehod sprejema dodatno, ne da bi se
vezal na njegovo končno obliko. Telesa pri GET prehod namenoma ne sprejme: po
RFC 9110, razdelek 9.3.1 tam nima določenega
pomena, posredniki ga zavržejo ali zahtevo zavrnejo, predpomnilnik, ki shranjuje po naslovu, pa bi
odgovor enega filtra vrnil za drugega.
| Pravilo | Razlog |
|---|---|
| Preverjeno, omejeno in zabeleženo kot branje | Klicatelj s pravico samo za branje sme to storiti; če bi se presojalo po metodi, bi potreboval pravico pisanja |
Telo se prebere šele po prijavi in odobritvi, omejeno z MaxBodyBytes | Branje telesa je delo; nepooblaščena zahteva ga ne sme sprožiti |
Možnosti v naslovu in telesu: 400 | Iz zahteve ne bi bilo razvidno, kateri od dveh $filter velja |
Samo text/plain (ali application/x-www-form-urlencoded) | JSON je druga oblika zahteve; brati ga kot možnosti bi pomenilo brati ga napačno |
Naslednja stran kaže na vir, ne na $query | Odjemalec ji sledi z GET; če je sama predolga, jo znova pošlje kot $query |
Po prevzemu se obe obliki obravnavata kot isto branje: isti prevajalnik, iste omejitve, isto tvorjenje strani. Koliko vrednosti sme navesti pogoj, zato ni odvisno od poti, temveč od oblike pogoja; glejte Dolgi seznami vrednosti.
Dolgi seznami vrednosti
Pogoj, kot je „ena od teh številk“, pride kot veriga enakosti: Nummer eq 1 or Nummer eq 2 or ….
Jezik filtrov OData 4.0 ne pozna in (uvede ga šele 4.01,
URL Conventions 4.01);
gonilnik ODBC zato tako zapiše IN (…) iz Accessa, tipizirani odjemalec pa enako zapiše preverjanje
pripadnosti množici. Če bi bila vsaka vrednost vezana posamično, bi bila vsaka lasten parameter, SQL Server pa jih v
enem stavku sprejme največ 2.098: klic ima 2.100 parametrov, dva od njih zasede sp_executesql sam.
Tipizirani odjemalec v preverjanju pripadnosti dovoli največ 20.000 vrednosti (od specifikacije vmesnika 0.2.0, prej 1.000); mejo preveri paket specifikacije vmesnika, preden zahteva zapusti proces.
Prehod takšno verigo zato združi. Več kot 100 enakosti na istem stolpcu znotraj or zasede en sam
parameter, ne glede na to, koliko jih je: prenesejo se kot dokument XML. Stavek dokument najprej prebere
v spremenljivko in stolpec primerja z vrednostmi iz nje, vsako prebrano v tipu, ki bi ga imel njen
parameter.
| Pravilo | Razlog |
|---|---|
| Do 100 vrednosti ostane vsaka vrednost lasten parameter | Optimizator takrat vidi same vrednosti, kratki seznami ključev, s katerimi aplikacija ponovno bere svoje zapise, pa ostanejo nespremenjeni (Access poizveduje po deset ključev) |
| XML, ne JSON in ne prenos tabelaričnih vrednosti | SQL Server XML bere na vsaki stopnji združljivosti. OPENJSON in STRING_SPLIT zahtevata stopnjo 130, prenos tabelaričnih vrednosti pa tip, ki bi ga bilo treba šele ustvariti v podatkovni zbirki |
| Dokument se enkrat prebere v spremenljivko | V samem pogoju bi SQL Server seznam za vsako preverjeno vrstico znova pretvoril; pri dolgih seznamih bi čas izvajanja rasel s številom vrednosti, pomnoženim s številom vrstic |
| Seznam zadene natanko zapise, ki bi jih iste vrednosti zadele kot parametri | Vsaka vrednost je v dokumentu v obliki, ki jo SQL Server brez izgube prebere nazaj (tabela spodaj) |
| Če seznam tega ne zmore, se veže vrednost za vrednostjo | Mešane vrste vrednosti, časovna točka zunaj obsega datetime za takšen stolpec, ura zunaj dneva, besedilo z znaki, ki jih XML ne more nositi, decimalne vrednosti, katerih najdaljši celoštevilski del in največja skala skupaj dajo več kot 38 mest. Takrat znova velja meja 2.098 vrednosti |
| Seznam je izrecno označen kot brez manjkajočih vrednosti | Pri NOT IN mora SQL Server sicer za vsako vrstico preveriti, ali seznam vsebuje manjkajočo vrednost – takrat pogoj ne bi zadel nobene vrstice. Z oznako to preverjanje odpade in NOT IN prek dolgega seznama ostane hiter |
Enakosti pod and se ne združujejo | (a eq 1 and b eq 2) or … – na primer pari sestavljenega ključa – ni seznam enega stolpca |
Brez izgube po tipu. Seznam v vsakem stolpcu zadene iste zapise kot posamično vezane vrednosti, tudi pri dvojnikih, praznih besedilih in besedilih samo iz presledkov, prelomih vrstic in znakih zunaj osnovne večjezične ravnine Unicode.
| Tip | Oblika v dokumentu | Zakaj ta oblika |
|---|---|---|
| Cela števila | števke, prebrane kot bigint | – |
decimal, numeric | števke, prebrane kot decimal(38, s) z največjo skalo seznama | Obe primerjavi sta natančni |
float, real | celoštevilska mantisa in potenca števila dve | Iz besedilne oblike je SQL Server 16 od 60.000 vrednosti prebral kot sosednjo vrednost (subnormalne in velike celoštevilske vrednosti); v tej obliki ni odstopala nobena |
datetime, smalldatetime | vnaprej zaokroženo na 1/300 s, kot gonilnik zaokroži parameter | Brez zaokroževanja nekatere vrednosti ne bi zadele istih zapisov |
datetime2, date, time, datetimeoffset | s sedmimi decimalnimi mesti | – |
| Besedilo | konci vrstic in tabulatorji kot znakovni sklic; prazna vrednost kot element brez besedila | Dobesedni pomik na začetek vrstice bi ob branju dokumenta postal pomik v novo vrstico. Primerja se po razvrščanju stolpca, z razlikovanjem velikih in malih črk ali brez njega |
| Binarne vrednosti | Base64 | – |
bit, uniqueidentifier | navaden zapis | – |
Kaj omejuje dolžino seznama: telo zahteve. Privzeta vrednost 1 MB za MaxBodyBytes zadošča
za približno 36.000 vrednosti pri kratkem imenu stolpca in kratkih številskih vrednostih; daljša
imena stolpcev in vrednosti seznam ustrezno skrajšajo. Meja 2.098 posameznih vrednosti še naprej velja
za vse, kar ni seznam – veliko različnih stolpcev, primerjave z gt ali lt, iskanje besedila in
verige z največ 100 vrednostmi na stolpec, ki skupaj dajo več. Takšna zahteva se z 429 („Die Anfrage
bindet zu viele Einzelwerte.“ (Zahteva veže preveč posameznih vrednosti.)) zavrne, preden doseže
podatkovno zbirko.
Predstavitve: JSON in XML
Vsak naslov lastnega vmesnika se konča na .json ali .xml; odloča končnica, ne glava Accept. Tako je
namenoma: več orodij za preglednice in poročila ne omogoča nastavitve glave, naslov pa lahko navede
vsako. Zahteva s končnico, ki ne navaja nobene od obeh predstavitev, se zavrne z 400, namesto da bi
molče dobila odgovor v JSON.
Uspešen odgovor in napaka sta v zahtevani predstavitvi. Odjemalec, ki zahteva XML, ob napaki pa bi dobil objekt JSON, ne bi mogel prebrati prav odgovora, ki ga najbolj potrebuje.
Oblika XML sledi stalnemu dogovoru za vrstice, ker JSON in XML nista simetrična: seznam nima lastnega imena elementa, saj njegovi vnosi nimajo ključa.
<?xml version="1.0" encoding="utf-8"?> <results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <data> <row> <nummer>4711</nummer> <GeändertAm>2026-09-22T21:16:00</GeändertAm> <bemerkung xsi:nil="true" /> <field name="Menge (kg)">12.5</field> </row> </data> <rowCount>1</rowCount> </results>
| Pravilo | Zakaj |
|---|---|
Vsak vnos seznama postane <row> | Vnos seznama nima ključa, iz katerega bi lahko nastalo ime elementa |
| Ime stolpca postane element | Tudi s preglasi (ä, ö, ü): veljavna imena XML niso omejena na ASCII |
Ime, ki ni ime XML, postane <field name="…"> | Na primer presledki, oklepaji, števka na začetku. Stolpec ni ne preimenovan ne izpuščen – klicatelj ga mora najti pod njegovim pravim imenom. V zahtevi ga navede v kodirani obliki, glejte Časovne točke, števila in imena |
Manjkajoča vrednost je prazen element z xsi:nil="true" | Praznega elementa brez te oznake ni mogoče razlikovati od praznega niza, pri besedilnem stolpcu, ki dopušča NULL, pa sta to dve različni stanji |
| Vrednosti so neodvisne od kulture in kot v JSON | Decimalno ločilo pika, časovna točka po ISO 8601, binarna vrednost kot Base64 |
| Znakov, ki jih XML prepoveduje (krmilni znaki razen tabulatorja in preloma vrstice), ni mogoče predstaviti | Odgovor se takrat konča z napako 503; takšne podatke berite prek JSON |
Lastni stavki (prepustna pot)
Treba jih je odobriti, glejte edina izjema.
Klicatelj brez pravice sql, katerega pravila navajajo alias, isti naslov doseže s preverjenimi
stavki; takrat dodatno velja razdelek Preverjeni stavki. Telo vsebuje stavek
in, če ima ograde, njihove vrednosti:
POST /api/v1/cf/fachdaten/sql.json
X-Api-Key: …
{
"sql": "SELECT b.name, COUNT(*) AS anzahl FROM apparat a JOIN betrieb b ON b.id = a.betrieb WHERE a.stand = @stand GROUP BY b.name",
"parameters": { "stand": 3 }
}
Vrednosti se prenesejo kot parametri, nikoli v besedilu. To tu ni zaščitni ukrep – besedilo tako
ali tako pripada klicatelju –, vendar preprečuje, da bi se vrednost razčlenila kot del sintakse; prav
to namreč iz datuma ali decimalnega števila glede na jezikovno nastavitev seje naredi drugo vrednost. Imena
parametrov so navadni identifikatorji in se pošiljajo brez @.
Odgovor ima običajno obliko uspeha, dopolnjeno s columns:
{
"columns": [
{ "name": "name", "type": "Edm.String", "nullable": true, "maxLength": 50 },
{ "name": "anzahl", "type": "Edm.Int32", "nullable": true }
],
"data": [ { "name": "Halle 1", "anzahl": 42 } ],
"rowCount": 1,
"executionTimeMs": 12
}
columns je le tukaj in ima svoj namen: pri objektu kataloga lahko odjemalec obliko vnaprej
prebere v dokumentu metapodatkov, pri lastnem stavku pa oblika nastane šele ob izvajanju. Odjemalec, ki bi
dobil le vrstice, bi moral tipe uganiti iz vrednosti, ki so po naključju v prvi vrstici – prazen
rezultat pa takrat sploh ne bi imel oblike. Zato je columns v odgovoru tudi takrat, ko stavek ne
vrne nobenega rezultata: kot prazen seznam, ki pove „ni stolpcev“, namesto manjkajočega polja, ki
ne pove ničesar. Imena tipov so ista kot v dokumentu metapodatkov vmesnika OData, z dvema razlikama:
vrednosti datetime, datetime2 in smalldatetime so zapisane kot stenska ura brez Z ali
zamika, čeprav se tip imenuje Edm.DateTimeOffset; stolpec neponujenega tipa ima "type": null.
Nadalje o obliki:
| Polje | Pomen na tej poti |
|---|---|
data | Prvi rezultat s stolpci. Števci, ki jih sprožilec izpiše prej, niso odgovor na zastavljeno vprašanje. Nadaljnji rezultati so v results, glejte spodaj |
affectedRowCount | Vsota spremenjenih vrstic prek vseh stavkov besedila; manjka, če stavek takšnega števca ne ustvari |
truncated | Učinkovala je omejitev števila vrstic aliasa; odgovor je skrajšan |
Vsak stolpec ima lastno ime. Stolpec brez imena (SELECT MAX(a), MIN(b)) se imenuje Column s svojim
položajem, kot v DataTable; podvojeno ime (SELECT a.id, b.id) dobi najmanjše število, ki ga naredi
enoličnega (id1). Vrstica vsebuje vrednosti pod imeni stolpcev; brez enoličnih imen bi se več
stolpcev zlilo v eno vrednost.
Časovna omejitev in omejitev števila vrstic prihajata iz Limits kot povsod drugje. Ključ, s
katerim se primerja pravilo pod Limits:Objects, se tu glasi {alias}/sql/ – vzorec, kot je
fachdaten/sql/*, torej nastavi omejitve te poti, ne da bi se dotaknil omejitev tabel. Tako lahko
dolga analiza dobi več časa kot podatkovni list.
Preverjeni stavki
Za klicatelja brez pravice sql prehod na istem naslovu sprejme stavek, če alias dovoljuje
preverjene stavke (AllowCheckedStatements, privzeto vklopljeno) in pravilo klicatelja navaja alias.
Prehod stavek razčleni, vsak navedeni objekt preveri glede na pravila klicatelja in izvede na novo
napisano različico, v kateri je vsak objekt naveden s svojo shemo. Kaj je dovoljeno, je opisano v
Preverjeni stavki.
Telo in odgovor sta enaka kot zgoraj; dodatno velja:
| Primer | Odgovor |
|---|---|
| Besedilo ni T-SQL | 400 z vrstico in stolpcem mesta napake |
Ločilna vrstica GO, sprememba sheme, dinamični SQL, ime s podatkovno zbirko ali strežnikom, nedovoljena funkcija ali oblika | 403; sporočilo navede obliko, pri več stavkih tudi številko zadevnega stavka (Anweisung 2 von 3: … (stavek 2 od 3: …)) |
| Objekt je neznan ali ni odobren za to, kar stavek z njim počne | 403; sporočilo navede objekt, kot je bil zapisan, in dostop. Neznano in prepovedano dobita enak odgovor |
V revizijsko sled se zapiše izvedena, na novo napisana različica.
Izhodni parametri, več nizov rezultatov, opisovanje
Trije dodatki na istem naslovu pokrijejo, kar je aplikacija ODBC vajena pri Microsoftovem gonilniku:
izhodne parametre in vrednosti RETURN, SQLMoreResults in stolpce pripravljenega stavka pred
izvajanjem. Veljajo enako za lastne in preverjene stavke; pri viru podatkov, katerega ponudnik jih ne
podpira, prehod odgovori z 400, še preden se obrne na podatkovno zbirko.
Izhodni parametri (outputs). Telo za vsak izhodni parameter navede njegov tip Edm; pri besedilu
in binarnih podatkih po želji tudi dolžino:
POST /api/v1/cf/fachdaten/sql.json
X-Api-Key: …
{
"sql": "EXEC @rueckgabe = dbo.auftrag_anlegen @kunde = @kunde, @nummer = @nummer OUTPUT",
"parameters": { "kunde": 4711 },
"outputs": { "rueckgabe": "Edm.Int32", "nummer": { "type": "Edm.String", "maxLength": 20 } }
}
| Pravilo | Zakaj |
|---|---|
Dovoljeni tipi: Edm.Boolean, Byte, Int16, Int32, Int64, Decimal, Single, Double, Date, TimeOfDay, DateTimeOffset, Guid, Binary, String; drugo ime → 400 | Izhodni parameter potrebuje svoj tip, preden se stavek izvede; SQL Server ga ne more sporočiti naknadno |
Brez dolžine: besedilo kot nvarchar(max), binarni podatki kot varbinary(max); Edm.Decimal kot decimal(38,10); Edm.DateTimeOffset kot datetime2 | Široki tipi za besedilo in binarne podatke ničesar ne odrežejo. Izgube: decimalna vrednost z več kot desetimi decimalnimi mesti se zaokroži, datetimeoffset izgubi svoj zamik |
Če je isto ime tudi v parameters, je parameter vhodni in izhodni | Tako Microsoftov gonilnik veže parameter INPUT_OUTPUT |
Imena brez @, navadni identifikatorji | Kot pri parameters |
Odgovor vsebuje vrednosti po imenih, null za NULL:
{ "columns": [], "data": [], "rowCount": 0, "outputs": { "rueckgabe": 0, "nummer": "A-2026-0815" }, "executionTimeMs": 9 }
outputs je v odgovoru le, če je zahteva navedla outputs. SQL Server vrednosti pošlje po zadnjem
nizu rezultatov; prehod zato prebere vse nize do konca, preden jih vpiše v odgovor.
Več nizov rezultatov (results). Če stavek vrne več kot en niz rezultatov s stolpci, je prvi kot
doslej v columns/data, vsak nadaljnji v tem vrstnem redu v results:
{
"columns": [ { "name": "id", "type": "Edm.Int32", "nullable": false } ],
"data": [ { "id": 1 } ],
"rowCount": 1,
"results": [
{ "columns": [ { "name": "name", "type": "Edm.String", "nullable": true, "maxLength": 50 } ],
"data": [ { "name": "Halle 1" } ], "rowCount": 1 }
],
"executionTimeMs": 11
}
Odjemalec, ki pozna le en niz, prebere isti odgovor kot prej. Omejitev števila vrstic velja za vsak
niz; skrajšan niz ima "truncated": true. Rezultati brez stolpcev (števci spremembe) se ne pojavijo
kot lasten niz.
Opisovanje brez izvajanja (describe). Z "describe": true prehod ničesar ne izvede in
odgovori s stolpci prvega niza rezultatov:
{ "sql": "SELECT id, name FROM dbo.betrieb WHERE id = @id", "parameters": { "id": 1 }, "describe": true }
{ "columns": [ { "name": "id", "type": "Edm.Int32", "nullable": false }, { "name": "name", "type": "Edm.String", "nullable": true, "maxLength": 50 } ], "data": [], "rowCount": 0, "executionTimeMs": 3 }
Opis se izvede z isto prijavo in z enakimi preverjanji kot izvajanje; klicatelj torej ne izve ničesar
o objektih, ki jih ne sme uporabljati. Vrednosti v parameters določajo le tipe ograd. Stavek,
ki vstavi vrstico, z describe ne vstavi nobene.
Ponovljene pisalne zahteve (Idempotency-Key)
Odjemalec na slabi povezavi pošlje spremembo, prehod jo shrani, odgovor pa se na povratni poti
izgubi. Odjemalec tega ne more razlikovati od zahteve, ki nikoli ni prispela. Če jo ponovi, nastane
drugi zapis ali konflikt pri pisanju (412) za spremembo, ki je že uspela, ker se je različica vrstice
medtem spremenila.
Če pisalna zahteva (POST, PATCH, DELETE) vsebuje glavo Idempotency-Key (do 128 vidnih znakov
ASCII, ki jih odjemalec izbere naključno), prehod na vsako ponovitev odgovori s shranjenim prvim
odgovorom in glavo Idempotent-Replayed: true, namesto da bi pisal še enkrat. Gonilnik ODBC jo pošlje
pri vsakem pisanju. Glava učinkuje pri vsaki metodi razen GET in HEAD in na vsakem naslovu, tudi
pri klicu procedure in pri lastnih stavkih.
| Primer | Odgovor |
|---|---|
| Isti ključ, ista metoda, naslov, prijava in isto telo | Shranjeni odgovor (status, telo, ETag, Location) |
| Ponovitev, medtem ko se prva še izvaja | Počaka, da se prva konča |
| Isti ključ z drugim telesom | 422 |
Prvi odgovor 401, 429 ali 5xx | Ni shranjen; ponovitev se dejansko izvede – po 5xx morda drugič |
Shranijo se uspehi in zavrnitve iz razlogov zahteve (400, 403, 404, 409, 412, 422),
10 minut. Mednje spada tudi 422 iz THROW procedure: ponovitev z istim ključem dobi shranjeni
odgovor (z istim correlationId), tudi če je razlog v podatkovni zbirki medtem odpravljen; nov
poskus potrebuje nov ključ. Odgovori se hranijo le v pomnilniku procesa: ponovni zagon to obdobje konča. Omejitve:
odgovori nad 1 MiB se ne shranijo, največ 10.000 vnosov (najstarejši izpadejo); telo zahteve z
Idempotency-Key se pred prijavo prebere v celoti, brez omejitve MaxBodyBytes; zavrnitve tega
preverjanja (400, 422) so navadno besedilo, ne v obliki napak. Za prijavo se upoštevata glava ključa
(ApiKeyHeader, privzeto X-Api-Key) in Authorization. Pooblastilo za shranjeni odgovor se ne
preveri znova – ključ, ki je bil medtem zaklenjen, ga prejema še do izteka desetih minut. Pri prijavi
Windows se upošteva račun, ne rokovanje, ki je na vsaki novi povezavi drugačno; naslov odjemalca se ne
upošteva, ker se lahko s prekinjeno povezavo spremeni.
Prenos namestitvenih paketov
GET /download/ navede namestitvene pakete iz mape Gateway:Downloads:Path (privzeto downloads,
relativno glede na koren vsebine; prazna vrednost prenos izklopi) z
velikostjo, SHA-256 in – samo pri datotekah .exe, iz njihovih podatkov o različici – različico, kot
JSON, za brskalnik kot spletno stran. GET /download/{datoteka} vrne datoteko. Ponujene so le datoteke neposredno v tej
mapi s končnico .msi ali .exe, brez prijave, ker ne vsebujejo gesel in ključev; za vsako drugo ime,
podmapo ali .. je odgovor 404. Omejitev hitrosti velja za vsak izvor posebej.
Stanje sheme za zaganjalnik WKL
GET /schema-state/{alias}/{izdelek} vrne stanje sheme izdelka v podatkovni zbirki aliasa, da
zaganjalnik WKL ponudi samo različice aplikacije, ki se z njo ujemajo:
{ "format": 1, "product": "Demo", "schema": 13, "applications": { "min": "2.4.0", "max": "" }, "updated": "2026-10-22T10:05:00Z" }
schema je različica sheme, applications pa razpon različic aplikacije, ki z njo delujejo (prazen
max: brez zgornje meje). Storitev prebere stanje iz wkl.Schemastand s prijavo vira podatkov; ta
prijava mora biti članica vloge podatkovne zbirke wkl_leser. Uporabniki v podatkovni zbirki ne
potrebujejo pravic.
| Odgovor | Pomen |
|---|---|
200 | Stanje kot JSON, z ETag |
304 | If-None-Match navaja trenutni ETag |
401 | Ni prijave Windows, Gateway:SchemaState:Anonymous pa je izklopljen |
404 | Neznan alias, njegov ponudnik ne izvaja posodobitev podatkovne zbirke ali izdelek nima stanja |
503 | Podatkovne zbirke ni mogoče prebrati |
Prijava je mogoča samo z Windows; odgovor dobi vsak račun, ki ga Windows prijavi, ker ne vsebuje podatkov iz podatkovne zbirke. Brez prijave storitev odgovori samo, če je vklopljen `Gateway:SchemaState:Anonymous`. Storitev odgovor hrani 30 sekund; podatkovno zbirko, ki je ni bilo mogoče prebrati, ob naslednjem klicu vpraša znova.
Sporočanje aplikacije in različice (X-Wkl-Application)
Aplikacija v vsaki zahtevi pošlje glavo X-Wkl-Application: <izdelek>/<različica>, na primer
Demo/2.4.0 (izdelek: črke, števke, ., -, _, največ 64 znakov; različica: dve do štiri
števila). Storitev si za vsak alias zapomni, kdaj je katera različica nazadnje poslala zahtevo.
Posodobitev podatkovne zbirke, ki starejše aplikacije prekine, čaka, dokler je kakšna starejša
različica poslala zahtevo znotraj okna seje. Zahteva brez veljavne glave šteje kot „neznana“; neznane
aplikacije posodobitve ne zadržijo. Vrednost je navedba programa, ne varnostna lastnost.
Opombe
- Klic procedure ni ovit v zunanjo transakcijo. Pisalne procedure tega izdelka imajo vsaka svojo; gnezdenje bi njihovo obravnavo napak molče spremenilo. Namesto tega se pred klicem izvede
SET XACT_ABORT ON. Če je odjemalec sam odprl transakcijo, se klic izvede v njej in brezXACT_ABORT, kot prek neposredne povezave:ROLLBACKv proceduri takrat konča tudi transakcijo odjemalca. Ustvarjeno pisanje pa je ovito v transakcijo: samo nima lastne, brez nje pa varovalo ne bi moglo razveljaviti dejanja, ki je zadelo napačno število vrstic. - Tabela z obveznim stolpcem, ki ga ni mogoče poimenovati, ne sprejme ustvarjanja. To zadeva le imena, katerih kodirana oblika bi bila daljša od 128 znakov; posebni znaki sami imena ne naredijo nepoimenljivega. Če je takšen stolpec obvezen in nima privzete vrednosti, noben klicatelj ne more v celoti navesti novega zapisa; prehod to sporoči vnaprej, namesto da bi čakal na zavrnitev podatkovne zbirke. Spreminjanje in brisanje nista prizadeta.
- Argument pri tabeli je ključ.
GET …/tables/X.json?Id=5prebere natanko ta zapis; argument, ki ne spada h ključu, se zavrne z400, namesto da bi bil prezrt; sicer bi zahteva vrnila prvo okno celotne tabele. - Šteje se v stavku, ne v gonilniku. Gonilnik prišteva vrstice, ki jih spreminjajo sprožilci; tabela s sprožilci zgodovine bi sicer za vsako posamezno spremembo sporočila več vrstic.
@@ROWCOUNTneposredno po stavku na to ne vpliva.