Ondersteuning van gegevenstypen

In tegenstelling tot de meeste SQL-databases vereist de SQL-database-engine van Adobe AIR niet dat tabelkolommen waarden van een bepaald type bevatten. Dit wordt ook niet afgedwongen. In plaats daarvan gebruikt de runtime twee concepten, opslagklassen en kolomaffiniteit, voor het beheer van gegevenstypen. In dit gedeelte worden opslagklassen en kolomaffiniteit beschreven, alsmede de manier waarop verschillen in gegevenstype onder verschillende omstandigheden worden opgelost:

Opslagklassen

Opslagklassen vertegenwoordigen de feitelijke gegevenstypen die worden gebruikt voor het opslaan van waarden in een database. De volgende opslagklassen worden gebruikt door de database:

NULL
De waarde bestaat uit een NULL-waarde.

INTEGER
De waarde bestaat uit een geheel getal met voorteken.

REAL
De waarde bestaat uit een zwevende-kommagetalwaarde.

TEXT
De waarde bestaat uit een teksttekenreeks (beperkt tot 256 MB).

BLOB
De waarde bestaat uit een BLOB (Binary Large Object), met andere woorden: ruwe binaire gegevens (beperkt tot 256 MB).

Alle waarden die als in een SQL-instructie ingesloten letterlijke waarden worden doorgegeven aan de database, of waarden die met parameters zijn gebonden aan een geprepareerde SQL-instructie, krijgen een opslagklasse toegewezen voordat de SQL-instructie wordt uitgevoerd.

Letterlijke waarden die deel uitmaken van een SQL-instructie, krijgen de opslagklasse TEXT toegewezen als deze tussen enkele of dubbele aanhalingstekens staan, INTEGER als de letterlijke waarde wordt opgegeven als getal zonder aanhalingstekens zonder decimaalteken of exponent, REAL als de letterlijke waarde bestaat uit een getal zonder aanhalingstekens met decimaalteken of exponent, en NULL als de waarde NULL is. Letterlijke waarden met de opslagklasse BLOB worden opgegeven met behulp van de notatie X'ABCD'. Zie Letterlijke waarden in expressies voor meer informatie.

Waarden die worden opgegeven als parameters met behulp van de associatieve array SQLStatement.parameters, krijgen de opslagklasse toegewezen die de oorspronkelijke gegevenstypebinding het meest benadert. Zo worden int-waarden gebonden als INTEGER-opslagklasse, krijgen getalwaarden de opslagklasse REAL, tekenreekswaarden opslagklasse TEXT en ByteArray-objecten opslagklasse BLOB.

Kolomaffiniteit

De affiniteit van een kolom is het aanbevolen type voor in die kolom opgeslagen gegevens. Wanneer een waarde wordt opgeslagen in een kolom (via een instructie van het type INSERT of UPDATE), probeert de runtime die waarde om te zetten van het gegevenstype naar de opgegeven affiniteit. Als bijvoorbeeld een datumwaarde (een ActionScript- of JavaScript Date-instantie) wordt ingevoegd in een kolom waarvan de affiniteit TEXT is, wordt de datumwaarde omgezet in de tekenreeksweergave (equivalent aan het aanroepen van de toString()-methode van het object) voordat deze wordt opgeslagen in de database. Als de waarde niet kan worden omgezet in de opgegeven affiniteit, treedt er een fout op en wordt de bewerking niet uitgevoerd. Wanneer een waarde wordt opgehaald uit de database via een SELECT-instructie, wordt deze geretourneerd als instantie van de klasse die overeenkomt met de affiniteit, ongeacht of de waarde is omgezet vanuit een ander gegevenstype toen deze is opgeslagen.

Als een kolom NULL-waarden accepteert, kan de ActionScript- of JavaScript-waarde null worden gebruikt als parameterwaarde om NULL op te slaan in de kolom. Wanneer een NULL-opslagklassewaarde wordt opgehaald in een SELECT-instructie, wordt deze altijd geretourneerd als de ActionScript- of JavaScript-waarde null, ongeacht de affiniteit van de kolom. Als een kolom NULL-waarden accepteert, controleert u altijd waarden die zijn opgehaald uit die kolom, om te bepalen of deze null zijn voordat u probeert de waarden om te zetten in een niet-null-type (zoals Number of Boolean).

Elke kolom in de database krijgt een van de volgende typen affiniteiten toegewezen:

  • TEXT (of String)

  • NUMERIC

  • INTEGER (of int)

  • REAL (of Number)

  • Boolean

  • Date

  • XML

  • XMLLIST

  • Object

  • NONE

TEXT (of String)

In een kolom met de affiniteit TEXT of String worden alle gegevens opgeslagen met de opslagklassen NULL, TEXT of BLOB. Als er numerieke gegevens worden ingevoegd in een kolom met de affiniteit TEXT, worden deze omgezet in een tekst voordat ze worden opgeslagen.

NUMERIC

Een kolom met de affiniteit NUMERIC bevat waarden met de opslagklassen NULL, REAL of INTEGER. Wanneer tekstgegevens worden ingevoegd in een kolom met affiniteit NUMERIC, wordt gepoogd deze om te zetten in een geheel getal of echt getal voordat deze worden opgeslagen. Als de conversie slaagt, wordt de waarde opgeslagen met de opslagklasse INTEGER of REAL (zo wordt een waarde '10,05' omgezet in de opslagklasse REAL voordat deze wordt opgeslagen). Als de conversie niet kan worden uitgevoerd, treedt er een fout op. Er wordt geen poging gedaan om de waarden om te zetten in een NULL-waarde. Een waarde die wordt opgehaald uit een kolom met affiniteit NUMERIC, wordt geretourneerd als instantie van het meest specifieke numerieke type waarin de waarde kan worden ingepast. Met ander woorden, als de waarde is een positief geheel getal of 0 is, wordt deze geretourneerd als een uint-instantie. Als het een negatief geheel getal betreft, wordt deze geretourneerd als een int-instantie. Als de waarde een zwevende-kommacomponent heeft en dus geen geheel getal is, wordt deze geretourneerd als een Number-instantie.

INTEGER (of int)

Een kolom die de affiniteit INTEGER gebruikt, gedraagt zich op dezelfde manier als een kolom met de affiniteit NUMERIC, met één uitzondering. Als de waarde die moet worden opgeslagen, een REAL-waarde heeft (bijvoorbeeld een Number-instantie) zonder zwevende-kommacomponent, of als de waarde een tekstwaarde is die kan worden omgezet in een REAL-waarde zonder zwevende-kommacomponent, wordt deze omgezet in een geheel getal en opgeslagen met de opslagklasse INTEGER. Als wordt gepoogd om een REAL-waarde op te slaan met een zwevende-kommacomponent, treedt er een fout op.

REAL (of Number)

Een kolom met de affiniteit REAL of NUMBER gedraagt zich als een kolom met de affiniteit NUMERIC, met dit verschil dat geheel-getalwaarden gedwongen worden omgezet in een zwevende-kommaweergave. Een waarde in een kolom REAL wordt altijd geretourneerd uit de database als een Number-instantie.

Booleaans

In een kolom met de affiniteit Boolean worden de waarden opgeslagen als waar of onwaar. Een Boolean-kolom accepteert een waarde die voorkomt uit een ActionScript- of JavaScript Boolean-instantie. Als code probeert om een tekenreekswaarde op te slaan, wordt een tekenreeks met een lengte groter dan nul beschouwd als waar en een lege tekenreeks is onwaar. Als code probeert om numerieke gegevens op te slaan, wordt elke niet-nulwaarde opgeslagen als waar en wordt 0 opgeslagen als onwaar. Wanneer een booleaanse waarde wordt opgehaald via een SELECT-instructie, wordt deze geretourneerd als een Boolean-instantie. Niet-NULL-waarden worden opgeslagen met de opslagklasse INTEGER (0 voor onwaar en 1 voor waar) en worden omgezet in booleaanse objecten wanneer gegevens worden opgehaald.

Date

In een kolom met de affiniteit Date worden datum- en tijdwaarden opgeslagen. Een Date-kolom is bedoeld voor het accepteren van waarden die voortkomen uit ActionScript- of JavaScript Date-instanties. Als wordt geprobeerd een tekenreekswaarde op te slaan in een kolom met affiniteit Date, probeert de runtime deze waarde om te zetten in een Juliaanse datum. Als de conversie mislukt, treedt er een fout op. Als code probeert om een Number-, int- of uint-waarde op te slaan, wordt niet gepoogd om de gegevens te valideren en wordt aangenomen dat het een geldige Juliaanse-datumwaarde betreft. Een Date-waarde die wordt opgehaald via een SELECT-instructie, wordt automatisch omgezet in een Date-instantie. Date-waarden worden opgeslagen als Juliaanse-datumwaarden met de opslagklasse REAL, waardoor sorteer- en vergelijkingsbewerkingen naar verwachting werken.

XML of XMLList

In een kolom met de affiniteit XML of XMLList, worden XML-structuren opgeslagen. Wanneer code probeert om gegevens op te slaan in een XML-kolom met een SQLStatement-parameter, probeert de runtime de waarde om te zetten en te valideren met behulp van de XML()- of XMLList()-functie van ActionScript. Als de waarde niet kan worden omgezet in geldige XML, treedt er een fout op. Als bij de poging tot opslag van de gegevens een letterlijke SQL-tekstwaarde wordt gebruikt (bijvoorbeeld INSERT INTO (col1) VALUES ('Invalid XML (no closing tag)')), wordt de waarde niet geparseerd of gevalideerd. Hiervan wordt aangenomen dat deze goed gestructureerd is. Wanneer een ongeldige waarde wordt opgeslagen, wordt deze bij ophalen geretourneerd als leeg XML-object. XML- en XMLList-gegevens worden opgeslagen met de opslagklasse TEXT of NULL.

Object

In een kolom met de affiniteit Object worden complexe ActionScript- of JavaScript-objecten opgeslagen, inclusief instanties van objectklassen alsook instanties van objectsubklassen zoals Array-instanties en zelfs instanties van aangepaste klassen. Object-kolomgegevens worden serieel geordend in de AMF3-indeling en opgeslagen met de opslagklasse BLOB. Wanneer een waarde wordt opgehaald, wordt de seriële ordening vanuit AMF3 ongedaan gemaakt en wordt de waarde geretourneerd als instantie van de klasse zoals deze werd opgeslagen. Houd er rekening mee dat de seriële ordening van bepaalde ActionScript-klassen, met name weergaveobjecten, niet ongedaan kan worden gemaakt om terug te gaan naar instanties van het oorspronkelijke gegevenstype. Voordat een instantie van een aangepaste klasse kan worden opgeslagen, moet u een alias voor de klasse registreren met de methode flash.net.registerClassAlias() (of in Flex door [RemoteObject]-metagegevens toe te voegen aan de klassendeclaratie). Voordat u de gegevens ophaalt, moet u dezelfde alias ook registreren voor de klasse. Alle gegevens waarvan de seriële ordening niet op de juiste manier ongedaan kan worden gemaakt, hetzij omdat de seriële ordening van de klasse van nature niet ongedaan kan worden gemaakt, hetzij omdat er een ontbrekende of niet-overeenstemmende klassenalias is, worden geretourneerd als anoniem object (een exemplaar van de klasse Object) met eigenschappen en waarden die overeenkomen met de oorspronkelijke instantie zoals deze is opgeslagen.

NONE

Een kolom met de affiniteit NONE heeft geen voorkeur een bepaalde opslagklasse. Er wordt geen poging ondernomen om de gegevens om te zetten voordat deze worden ingevoegd.

Affiniteit bepalen

Het type affiniteit van een kolom wordt bepaald door het gedeclareerde type van de kolom in de instructie CREATE TABLE. Bij het bepalen van het type worden de volgende regels (niet-hoofdlettergevoelig) toegepast:

  • Als het gegevenstype van de kolom een van de tekenreeksen CHAR, CLOB, STRI of TEXT bevat, heeft die kolom de affiniteit TEXT/String. U ziet dat het type VARCHAR de tekenreeks CHAR bevat en daarom de affiniteit TEXT krijgt toegewezen.

  • Als het gegevenstype voor de kolom de tekenreeks BLOB bevat of als er geen gegevenstype is opgegeven, heeft de kolom de affiniteit NONE.

  • Als het gegevenstype voor de kolom de tekenreeks XMLL bevat, heeft de kolom de affiniteit XMLList.

  • Als het gegevenstype voor de kolom de tekenreeks XML bevat, heeft de kolom de affiniteit XML.

  • Als het gegevenstype voor de kolom de tekenreeks OBJE bevat, heeft de kolom de affiniteit Object.

  • Als het gegevenstype voor de kolom de tekenreeks BOOL bevat, heeft de kolom de affiniteit Boolean.

  • Als het gegevenstype voor de kolom de tekenreeks DATE bevat, heeft de kolom de affiniteit Date.

  • Als het gegevenstype voor de kolom de tekenreeks INT (inclusief UINT) bevat, is de toegewezen affiniteit INTEGER/int.

  • Als het gegevenstype voor de kolom een van de tekenreeksen REAL, NUMB, FLOA of DOUB bevat, heeft de kolom de affiniteit REAL/Number.

  • In alle andere gevallen is de affiniteit NUMERIC.

  • Als een tabel wordt gemaakt met een instructie CREATE TABLE t AS SELECT..., wordt voor geen van de kolommen een gegevenstype opgegeven en krijgen deze de affiniteit NONE toegewezen.

Gegevenstypen en vergelijkingsoperatoren

De volgende binaire vergelijkingsoperatoren =, <, <=, >= en != worden ondersteund, samen met een bewerking voor het testen van het lidmaatschap, IN, en de ternaire vergelijkingsoperator BETWEEN. Zie Operatoren voor details over deze operatoren.

De resultaten van een vergelijking zijn afhankelijk van de opslagklassen van de twee waarden die worden vergeleken. Bij de vergelijking van twee waarden worden de volgende regels toegepast:

  • Een waarde met opslagklasse NULL wordt beschouwd als kleiner dan elke andere waarde (inclusief een andere waarde met de opslagklasse NULL).

  • Een INTEGER- of REAL-waarde is kleiner dan een willekeurige TEXT- of BLOB-waarde. Wanneer een INTEGER- of REAL-waarde wordt vergeleken met een andere INTEGER- of REAL-waarde, wordt een numerieke vergelijking uitgevoerd.

  • Een TEXT-waarde is kleiner dan een BLOB-waarde. Bij de vergelijking van twee TEXT-waarden wordt een binaire vergelijking uitgevoerd.

  • Wanneer twee BLOB-waarden worden vergeleken, wordt het resultaat altijd bepaald met een binaire vergelijking.

De ternaire operator BETWEEN wordt altijd omgevormd tot de equivalente binaire expressie. Zo wordt a BETWEEN b AND c omgevormd tot a >= b AND a <= c, zelfs als dit inhoudt dat er andere affiniteiten worden toegepast op a in elk van de vergelijkingen die nodig zijn voor het evalueren van de expressie.

Expressies van het type a IN (SELECT b ....) worden afgehandeld met de drie regels die eerder zijn opgenoemd voor binaire vergelijkingen, namelijk op een vergelijkbare manier als a = b. Als bijvoorbeeld b een kolomwaarde is en a een expressie, wordt de affiniteit van b toegepast op a voor alle vergelijkingen die plaatsvinden. De expressie a IN (x, y, z) wordt omgevormd tot a = +x OR a = +y OR a = +z. De waarden rechts van de operator IN (de waarden x, y en z in dit voorbeeld) worden als expressies beschouwd, zelfs als deze toevallig kolomwaarden zijn. Als de waarde links van de operator IN een kolom is, wordt de affiniteit van die kolom gebruikt. Als de waarde een expressie is, vindt geen conversie plaats.

Hoe vergelijkingen worden uitgevoerd, kan ook worden beďnvloed door het gebruik van een COLLATE-component. Zie COLLATE voor meer informatie.

Gegevenstypen en wiskundige operatoren

Voor elk van de ondersteunde wiskundige operatoren, *, /, %, + en -, wordt de affiniteit NUMERIC toegepast op elke operand voordat de expressie wordt geëvalueerd. Als een bepaalde operand niet kan worden omgezet in de opslagklasse NUMERIC, leidt de evaluatie van de expressie tot NULL.

Wanneer de samenvoegingsoperator || wordt gebruikt, wordt elke operand omgezet naar de opslagklasse TEXT voordat de expressie wordt geëvalueerd. Als een bepaalde operand niet kan worden omgezet in de opslagklasse TEXT, is het resultaat van de expressie NULL. In twee situaties kunnen operanden mogelijk niet worden omgezet: als de waarde van de operand NULL is, of als het een BLOB betreft met andere opslagklasse dan TEXT.

Gegevenstypen en sorteren

Wanneer waarden worden gesorteerd met een ORDER BY-component, komen waarden met opslagklasse NULL op de eerste plaats. Deze worden gevolgd door INTEGER- en REAL-waarden die elkaar afwisselen in een numerieke volgorde, gevolgd door TEXT-waarden in binaire volgorde of op basis van de opgegeven sortering (BINARY of NOCASE). Als laatste komen de waarden BLOB in binaire volgorde. Vóór de sortering vinden er geen omzettingen van opslagklassen plaats.

Gegevenstypen en groeperen

Bij het groeperen van waarden met de GROUP BY-component worden waarden met verschillende opslagklassen als afzonderlijk van elkaar beschouwd. Een uitzondering hierop vormen echter INTEGER- en REAL-waarden die als gelijkwaardig aan elkaar worden beschouwd als deze numeriek equivalent zijn. Als resultaat van een GROUP BY-component worden op geen van de waarden affiniteiten toegepast.

Gegevenstypen en samengestelde SELECT-instructies

De samengestelde SELECT-operatoren UNION, INTERSECT en EXCEPT voeren impliciete vergelijkingen van waarden uit. Voordat deze vergelijkingen worden uitgevoerd, wordt op elke waarde mogelijk een affiniteit toegepast. Indien er al een affiniteit is, wordt dezelfde affiniteit toegepast op alle waarden die kunnen worden geretourneerd in één kolom van de samengestelde SELECT-resultatenset. De affiniteit die wordt toegepast, is de affiniteit van de kolom die wordt geretourneerd door de eerste samengestelde SELECT-instructie die op die positie een kolomwaarde heeft (en niet een of andere expressie). Als voor een bepaalde samengestelde SELECT-kolom geen van de samengestelde SELECT-instructies een kolomwaarde retourneert, wordt er geen affiniteit toegepast op de waarden van die kolom voordat er wordt vergeleken.