Časovne točke, števila in imena
Ali vrednost prispe tako, kot je bila mišljena, določajo tri pravila: vrednosti se vežejo po tipu
stolpca, ne kot besedilo; časovna točka brez časovnega pasu je prek OData prikazana z Z; imena z
znaki, ki jih OData ne dovoljuje, se prenašajo kodirana. Ta stran vsa tri pravila pojasni na enem
mestu, referenčne strani pa kažejo nanjo.
Ključne funkcije
- Datumi, časovne točke, zneski in vrednosti s plavajočo vejico prispejo natančno, ne glede na jezikovno nastavitev.
- Branje in pisanje časovnih točk prek OData sta simetrična.
- Dosegljivo je vsako ime, ki ga sprejme SQL Server, če njegova kodirana oblika ni daljša od 128 znakov.
Osnovni pojmi
Vrednosti po tipu stolpca
Vrednosti se vežejo po tipu stolpca, ne kot besedilo. Datum iz telesa zahteve pride v SQL Server
kot datum. Kot besedilo bi ga SQL Server razčlenil po jezikovni nastavitvi povezave in pri nemški
nastavitvi bi iz 2023-06-01 nastal 6. januar – in tak bi ostal shranjen. Iz tega sledijo pravila:
- Datum je sprejet samo v obliki ISO;
01.06.2023je dvoumen. - Časovno točko s časovnim pasom za stolpec brez časovnega pasu lastni vmesnik HTTP zavrne, prek OData pa se pretvori (glejte Časovne točke brez časovnega pasu).
- Znesek se veže natančno, tudi v eksponentnem zapisu: vrednost JSON, kot je
1.5E2, se za decimalni stolpec prebere iz zaporedja števk in ohrani vse števke. To velja za do 38 števk, kolikor jih hranidecimal(38, s), pri pisanju in pri branju; daljše število se za decimalni stolpec zavrne. - Logična vrednost za besedilni stolpec je zavrnjena.
- Vrednost s plavajočo vejico prispe bit za bitom. Prehod jo prebere iz zaporedja števk in je ne pretvarja iz tipa
decimal, saj ta pretvorba ne zaokroža pravilno.
Časovna točka se veže v tipu svojega stolpca, pri pisanju in v filtru: za stolpec datetime2
kot datetime2, za stolpec date kot date. Če bi tip izpeljali samo iz vrednosti, bi bila vsaka
časovna točka datetime – zaokrožena na 1/300 sekunde in omejena na leto 1753 in pozneje. Zaradi
tega pravila filter najde tudi shranjeno vrednost s sedmimi decimalnimi mesti, zapisana vrednost pa
ohrani vseh sedem mest, tudi v letu 1.
Manjkajoča vrednost za binarni stolpec se veže kot binarna vrednost. Brez tipa bi null prišel
v SQL Server kot nvarchar, SQL Server pa tipa nvarchar ne pretvori samodejno v binary,
varbinary ali image – niti manjkajoče vrednosti ne. Vstavljanje bi se tedaj končalo z napako 257.
Access polj, ki niso nastavljena, ne navede, CommandBuilder v ADO.NET pa navede vse stolpce, tudi
stolpec varbinary z vrednostjo null.
Datum naj bo v filtru časovna točka, ne niz. V vmesniku OData
ge 2023-06-01T00:00:00Z(literal OData 4) inge datetime'2023-06-01T00:00:00'(literal OData 3, ki ga zapišeta Access in Power Query) vežeta časovno točko,ge '2023-06-01'pa veže besedilo. Za stolpec tipadatetimealismalldatetimeSQL Server to besedilo razčleni po jezikovni nastavitvi povezave: v podatkovni zbirki z nemško nastavitvijo iz'2023-06-01'nastane 6. januar – brez napake in brez opozorila, le z drugačnim naborom vrstic.
Decimalna vrednost se veže natančno, ne kot število s plavajočo vejico. SQL Server daje plavajoči vejici prednost pred decimalnim tipom (Microsoft: Data type precedence). Parameter s plavajočo vejico v primerjavi s stolpcem
decimalalimoneyzato pretvori stolpec: indeksa na njem ni več mogoče uporabiti, primerja pa se le približek shranjene vrednosti. Dve različni decimalni vrednosti se lahko preslikata v isto vrednost s plavajočo vejico:DecimalField eq 123456789012.345678najde eno vrstico, isti filter z…678dpa dve. Plavajoča vejica se uporabi samo tam, kjer jo zahteva literal – pri končnicifalid, pri eksponentnem zapisu ali pri vrednosti zunaj natančnega obsega.
Zavrnjeni literal ima večje posledice, kot se zdi. Odjemalec za preglednice ali poročila napake
400ne prikaže, temveč pogoj izpusti in prebere ves objekt. Ciljna poizvedba se tako spremeni v branje cele tabele, ki lahko pri veliki tabeli preseže časovno omejitev. Zato so literali protokola del specifikacije vmesnika in ne zgolj udobje.
Časovne točke brez časovnega pasu
Časovna točka brez časovnega pasu je prikazana z
Z. OData v4 nima tipa za časovno točko brez časovnega pasu. Prehod zapiše shranjeni lokalni čas in dodaZ. TaZzahteva protokol in ne pove ničesar o shranjenem času, saj podatkovna zbirka ne ve, v katerem časovnem pasu so njene vrednosti nastale. Temu ustrezno se vrednost filtra s časovnim pasom za tak stolpec pretvori v univerzalni koordinirani čas (UTC):ge 2023-01-01T00:00:00+01:00primerja z 31. 12. 2022 ob 23.00. Obe pravili sta povezani in se vedno spreminjata skupaj.
Prek OData se časovna točka s časovnim pasom pri pisanju pretvori v UTC. Pri branju prehod vrednosti stolpca brez časovnega pasu doda
Z, zato odjemalec, ki vrstico prebere, spremeni in pošlje nazaj, pošlje tudi taZ; prehod ga spet odstrani. Enako se pretvori vsak drug zamik:17:00+02:00se shrani kot 15.00 – ista časovna točka, kot jo ima v mislih filter s časovnim pasom. Lastni vmesnik HTTP (/api/v1/cf/…) pa časovno točko s časovnim pasom za tak stolpec zavrne, ker takega dogovora ne pozna.
Tipi
| Tip stolpca | Tip Edm | Opomba |
|---|---|---|
bit, tinyint, smallint, int, bigint | Boolean, Byte, Int16, Int32, Int64 | Int64 je zapisan kot število JSON; odjemalec, ki števila bere kot plavajočo vejico IEEE 754 (npr. JavaScript), izgubi števke nad 2^53 |
decimal, numeric, money, smallmoney | Decimal | natančnost in število decimalnih mest v shemi; natančno zapisano kot število JSON – z enako omejitvijo za odjemalce, ki števila berejo s plavajočo vejico |
real, float | Single, Double | |
date, time | Date, TimeOfDay | |
datetime, datetime2, smalldatetime | DateTimeOffset | lokalni čas z Z; glejte Časovne točke brez časovnega pasu |
datetimeoffset | DateTimeOffset | s shranjenim časovnim pasom |
besedilni tipi in xml | String | dolžina: pri nchar/nvarchar v znakih, pri char/varchar v bajtih shrambe (pri razvrščanjih UTF-8 več, kot je znakov) |
uniqueidentifier | Guid | |
| binarni tipi, različica vrstice | Binary | |
hierarchyid, geography, geometry | Binary | shranjeni bajti, isti, kot jih vrne ODBC Driver 18; zapisana vrednost se preda kot bajti, SQL Server jo pretvori nazaj |
sql_variant | String | shranjena vrednost kot besedilo v obliki njenega osnovnega tipa, kot jo vrne ODBC Driver 18: 42, 12.345, 2026-10-29 08:00:00.000; zapisana vrednost se shrani kot besedilo |
vector, json, tipi CLR, ki jih določi aplikacija | – | niso na voljo: ne prek OData ne pri branju brez seznama polj ne pri ponovnem branju po pisanju v lastnem vmesniku HTTP |
Nekaterih tipov ni mogoče primerjati ali razvrščati. SQL Server ne primerja in ne razvršča tipov
text, ntext, image, xml, geography in geometry. Vrednost sql_variant primerja po
njenem osnovnem tipu: vrednost s številom 42 ni enaka besedilu '42', filter pa ne bi brez opozorila
našel ničesar. Prek OData storitev zato primerjavo v $filter in razvrščanje v $orderby po takem
stolpcu zavrne z 400 in navede stolpec; preverjanje manjkajoče vrednosti (eq null) in iskanje po
besedilu ostaneta dovoljena. hierarchyid je urejen po svojih bajtih in ga je mogoče primerjati in
razvrščati, z binarno vrednostjo v šestnajstiškem zapisu: binary'5B40'. Lastni vmesnik HTTP primerjavo
nespremenjeno preda SQL Serverju; primerjava po sql_variant tam najde vrednost le, če je shranjena v
istem osnovnem tipu.
vector (SQL Server 2025) je naveden v sistemskem katalogu kot varbinary, pretvorbo v varbinary(max) pa
zavrne. Katalog ga zato vodi pod lastnim imenom. Kot varbinary bi bil ponujen kot binarna
vrednost, čeprav to ni, žig vrstice nad tabelo pa bi povzročil, da bi se vsako branje končalo z
napako.
Imena s posebnimi znaki
V oglatih oklepajih SQL Server v imenu sprejme skoraj vsak znak: [F&E], [Ein/Aus],
[Prüf-Kennung], [Pos. Nr.]. OData v imenu dovoljuje samo črke, števke in podčrtaj, največ
128 znakov (SimpleIdentifier v
OData CSDL XML 4.01,
razdelek “SimpleIdentifier”). Prehod zato taka imena kodira na enak način, kot to počneta SQL
Server pri FOR XML in SharePoint pri imenih polj: znak, ki na svojem mestu ni dovoljen, se zamenja
z _x, njegovo kodo v štirih šestnajstiških števkah (z velikimi črkami) in _; zunaj osnovne
večjezične ravnine Unicode ima koda osem števk.
| Shranjeno | Pri prenosu |
|---|---|
F&E | F_x0026_E |
Ein/Aus | Ein_x002F_Aus |
Prüf-Kennung | Prüf_x002D_Kennung |
Pos. Nr. | Pos_x002E__x0020_Nr_x002E_ |
Geräte Liste | Geräte_x0020_Liste |
1Nummer | _x0031_Nummer |
Nr# | Nr_x0023_ |
GeändertAm | GeändertAm (nespremenjeno) |
A_x0020_B (dobesedno ime) | A_x005F_x0020_B |
| Pravilo | Razlog |
|---|---|
| Črke (tudi s strešicami in drugimi diakritičnimi znamenji), podčrtaj in števke od drugega znaka naprej ostanejo nespremenjeni | Ime brez posebnih znakov ostane tako, kot je |
Kodirajo se tudi @, # in $ | SQL Server jih v običajnem imenu dovoljuje, OData pa ne; nekodirani bi dokument sheme naredili neveljaven |
Podčrtaj, ki je videti kot začetek kodiranja, se kodira tudi sam (_x005F_) | Sicer bi A B in stolpec z dobesednim imenom A_x0020_B dobila isto ime |
Velja za sheme, tabele, poglede in stolpce: v $metadata, v poti, v $select, $filter in $orderby, v ključu in v telesu | Klicatelj objekt povsod imenuje enako |
Tudi konfiguracija objekte imenuje enako (RowStampTables, KeylessWriteTables, omejitve) | Objekte imenuje tako kot zahteva |
V lastnem vmesniku HTTP (/api/v1/cf/…) zahteva uporablja kodirano ime, odgovor pa ohrani shranjeno | Odgovori tega vmesnika uporabljajo imena tako, kot jih vodi podatkovna zbirka; glejte Predstavitve |
| Zaradi imena sta izpuščena samo objekt ali stolpec, katerega kodirano ime bi bilo daljše od 128 znakov (sicer manjkajo še stolpci nepodprtih tipov in objekti brez podprtega stolpca) | Daljši identifikator ni mogoč; dolgo ime z veliko presledki lahko mejo preseže |
V stavek gre vedno samo zapis iz kataloga: prehod kodirano ime poišče v katalogu in ga nadomesti s
shranjenim imenom, preden ga zapiše v stavek – v oglatih oklepajih in s podvojenim ]. Gonilnik ODBC
imena za Access prevede nazaj, zato je F&E tam spet prikazan kot F&E.
Kako ime varno pride v stavek. Imena s preglasi in strešicami so dovoljena, čeprav podatkovne
zbirke identifikatorje primerjajo po razvrščanjih, ki diakritične znake obravnavajo različno; sicer
v tabelo z obveznim stolpcem, kot je GeändertAm, sploh ne bi bilo mogoče pisati. To mejo varujeta
dva koraka: ime se poišče v katalogu, ki ga je prehod prebral iz podatkovne zbirke, v stavek pa gre
samo zapis iz kataloga, v oglatih oklepajih in s podvojenim zaklepajem. Primerjava je ordinalna –
velike in male črke se izenačijo, diakritični znaki ne. Kodirano ime se primerja s kodiranimi imeni
kataloga, nikoli s shranjenimi; sicer bi stolpec z dobesednim imenom F_x0026_E lahko zamenjali z
F&E.