Prise en charge des types de données

Contrairement à la plupart des bases de données SQL, le moteur de la base de données SQL d’Adobe AIR ne requiert pas ou n’impose pas que les colonnes des tables contiennent des valeurs d’un type donné. Le moteur d’exécution utilise plutôt deux concepts, les classes de stockage et l’affinité de colonne, pour contrôler les types de données. Cette section décrit les classes de stockage et l’affinité de colonne, ainsi que la résolution des différences de types de données selon les cas :

Classes de stockage

Les classes de stockage représentent les types de données réels utilisés pour stocker des valeurs dans une base de données. La base de données fait appel aux classes de stockage suivantes :

NULL
La valeur est une valeur NULL.

INTEGER
La valeur est un nombre entier signé.

REAL
La valeur est une valeur à virgule flottante.

TEXT
La valeur est une chaîne texte (de 256 Mo au plus).

BLOB
La valeur est un BLOB (Binary Large Object), c’est-à-dire des données binaires brutes (de 256 Mo au plus).

Toutes les valeurs, fournies à la base de données sous forme de valeurs littérales intégrées à une instruction SQL ou de valeurs liées à l’aide de paramètres à une instruction SQL préparée, se voient affecter une classe de stockage avant l’exécution de l’instruction SQL.

Les valeurs littérales qui font partie d’une instruction SQL se voient affecter la classe de stockage TEXT si elles sont placées entre guillemets simples ou doubles, INTEGER si la valeur littérale est un nombre sans guillemet et sans décimale ou exposant, REAL si la valeur littérale est un nombre sans guillemet avec décimale ou exposant et NULL si la valeur est NULL. Les valeurs littérales avec classe de stockage BLOB sont spécifiées par la notation X'ABCD’. Pour plus d’informations, voir la section consacrée aux valeurs littérales dans les expressions.

Les valeurs fournies en tant que paramètres via le tableau associatif SQLStatement.parameters se voient affecter la classe de stockage la plus proche de la liaison native du type de données. Par exemple, les valeurs int sont liées en tant que classe de stockage INTEGER, les valeurs Number obtiennent la classe de stockage REAL, les valeurs String obtiennent la classe de stockage TEXT et les objets ByteArray obtiennent la classe de stockage BLOB.

Affinité de colonne

L’ affinité d’une colonne correspond au type recommandé des données stockées dans cette colonne. Lorsqu’une valeur est stockée dans une colonne (par une instruction INSERT ou UPDATE), le moteur d’exécution tente de convertir le type de données de cette valeur en l’affinité spécifiée. Par exemple, si une valeur Date (occurrence de Date ActionScript ou JavaScript) est insérée dans une colonne dont l’affinité est TEXT, elle est convertie en représentation String (ce qui équivaut à appeler la méthode toString() de l’objet) avant d’être stockée dans la base de données. Si la valeur ne peut pas être convertie en l’affinité spécifiée, une erreur est renvoyée et l’opération n’est pas exécutée. Lorsqu’une valeur est récupérée dans la base de données par une instruction SELECT, elle est renvoyée sous forme d’occurrence de la classe correspondant à l’affinité, qu’elle ait été ou non convertie à partir d’un autre type de données lors de son stockage.

Si une colonne accepte les valeurs NULL, la valeur null ActionScript ou JavaScript peut servir de valeur de paramètre pour stocker NULL dans la colonne. Lorsqu’une valeur de classe de stockage NULL est récupérée dans une instruction SELECT, elle est toujours renvoyée en tant que valeur null ActionScript ou JavaScript, quelle que soit l’affinité de la colonne. Lorsqu’une colonne accepte les valeurs NULL, vérifiez toujours les valeurs récupérées dans cette colonne pour déterminer si elles sont null avant de tenter d’attribuer aux valeurs un type qui ne peut pas être null (Number ou Boolean, par exemple).

L’une des affinités de type suivantes est affectée à chaque colonne de la base de données :

  • TEXT (ou String)

  • NUMERIC

  • INTEGER (ou int)

  • REAL (ou Number)

  • Boolean

  • Date

  • XML

  • XMLLIST

  • Object

  • NONE

TEXT (ou String)

Une colonne d’affinité TEXT ou String stocke toutes les données à l’aide des classes de stockage NULL, TEXT ou BLOB. Si des données numériques sont insérées dans une colonne dont l’affinité est TEXT, elles sont converties au format texte avant d’être stockées.

NUMERIC

Une colonne d’affinité NUMERIC stocke des valeurs à l’aide des classes de stockage NULL, REAL ou INTEGER. Lorsque des données texte sont insérées dans une colonne NUMERIC, le système tente de les convertir en nombres entiers ou réels avant de les stocker. Si la conversion aboutit, la valeur est stockée à l’aide de la classe de stockage INTEGER ou REAL (la valeur « 10,05 » est par exemple convertie en classe de stockage REAL avant d’être stockée). S’il est impossible d’effectuer la conversion, il se produit une erreur. Aucune tentative de conversion d’une valeur NULL est exécutée. Une valeur récupérée dans une colonne NUMERIC est renvoyée sous forme d’occurrence du type numérique le plus spécifique adapté à la valeur. En d’autres termes, si la valeur est un nombre entier positif ou 0, elle est renvoyée sous forme d’occurrence d’uint. S’il s’agit d’un nombre entier négatif, elle est renvoyée sous forme d’occurrence d’int. Enfin, s’il s’agit d’un composant à virgule flottante (et non d’un nombre entier), elle est renvoyée sous forme d’occurrence de Number.

INTEGER (ou int)

Une colonne qui utilise l’affinité INTEGER se comporte comme une colonne dont l’affinité est NUMERIC, à une exception près. Si la valeur à stocker est une valeur réelle (par exemple une occurrence de Number) sans composant à virgule flottante, ou si la valeur est une valeur de texte pouvant être convertie en valeur réelle sans composant à virgule flottante, elle est convertie en nombre entier et stockée à l’aide de la classe de stockage INTEGER. En cas de tentative de stockage d’une valeur réelle avec un composant à virgule flottante, une erreur se produit.

REAL (ou Number)

Une colonne dont l’affinité est REAL ou NUMBER se comporte comme une colonne d’affinité NUMERIC, sauf qu’elle convertit les valeurs entières en représentation à virgule flottante. Les valeurs d’une colonne REAL sont toujours renvoyées à partir de la base de données sous forme d’occurrences de Number.

Boolean

Une colonne d’affinité BOOLEAN stocke des valeurs true ou false. Une colonne BOOLEAN gère une valeur correspondant à une occurrence de Boolean ActionScript ou JavaScript. Si le code tente de stocker une valeur String, une valeur String dont la longueur est supérieure à zéro est considérée comme true, une valeur String vide comme false. Si le code tente de stocker des données numériques, toute valeur autre que zéro est stockée en tant que true et 0 est stocké en tant que false. Lorsqu’une valeur Boolean est récupérée par une instruction SELECT, elle est renvoyée en tant qu’occurrence de Boolean. Les valeurs non NULL sont stockées à l’aide de la classe de stockage INTEGER (0 pour false et 1 pour true) et sont converties en objet Boolean lors de la récupération des données.

Date

Une colonne d’affinité DATE stocke des valeurs de date et d’heure. Une colonne DATE est conçue pour accepter des valeurs qui sont des occurrences de Date ActionScript ou JavaScript. En cas de tentative de stockage d’une valeur String dans une colonne DATE, le moteur d’exécution tente de la convertir en date julienne. Si la conversion échoue, il se produit une erreur. Si le code tente de stocker une valeur Number, int ou uint, il ne se produit pas de tentative de validation des données et il est considéré comme acquis qu’il s’agit d’une valeur de date julienne valide. Une valeur DATE récupérée par une instruction SELECT est automatiquement convertie en occurrence de Date. Les valeurs DATE étant stockées en tant que valeurs de dates juliennes avec la classe de stockage REAL, les opérations de tri et de comparaison fonctionnent comme prévu.

XML ou XMLList

Une colonne qui utilise une affinité XML ou XMLLIST stocke des structures XML. Lorsque le code tente de stocker des données dans une colonne XML en utilisant un paramètre SQLStatement, le moteur d’exécution tente de convertir et de valider la valeur à l’aide de la fonction ActionScript XML() ou XMLList(). Si la valeur ne peut pas être convertie en code XML valide, une erreur se produit. Si la tentative de stockage des données utilise une valeur de texte SQL littérale (INSERT INTO (col1) VALUES ('Invalid XML (no closing tag)', par exemple), la valeur n’est ni analysée, ni validée, car son format est considéré comme correct. Si une valeur non valide est stockée, elle est renvoyée en tant qu’objet XML vide lorsqu’elle est récupérée. Les données XML et XMLLIST sont stockées à l’aide de la classe de stockage TEXT ou NULL.

Object

Une colonne d’affinité Object stocke des objets complexes ActionScript ou JavaScript, y compris des occurrences de la classe Object, des occurrences des sous-classes Object telles que les occurrences d’Array, voire des occurrences des classes personnalisées. Les données de la colonne Object sont sérialisées au format AMF3 et stockées avec la classe de stockage BLOB. Lorsqu’une valeur est récupérée, elle est désérialisée du format AMF3 et renvoyée sous forme d’occurrence de leur classe d’origine. Notez que certaines classes ActionScript, en particulier les objets d’affichage, ne peuvent pas être désérialisées en tant qu’occurrences de leur type de données d’origine. Avant de stocker une occurrence de classe personnalisée, vous devez enregistrer un alias pour la classe avec la méthode flash.net.registerClassAlias() (ou dans Flex, en ajoutant des métadonnées [RemoteObject] à la déclaration de la classe). Avant de récupérer les données, vous devez également enregistrer le même alias pour la classe. Toutes les données qui ne peuvent pas être désérialisées correctement, que le problème soit inhérent à la classe ou dû au fait qu’un alias de classe est introuvable ou ne correspond pas à la valeur requise, sont renvoyées sous forme d’objet anonyme (une occurrence de la classe Object) dont les propriétés et les valeurs correspondent à l’occurrence d’origine telle qu’elle a été stockée.

NONE

Une colonne d’affinité NONE ne privilégie aucune classe de stockage. Elle ne tente pas de convertir les données avant de les insérer.

Identification de l’affinité

L’affinité de type d’une colonne est déterminée par le type déclaré de la colonne dans l’instruction CREATE TABLE. Lors de la détermination du type, les règles suivantes (non sensibles à la casse) sont appliquées :

  • Si le type de données de la colonne contient l’une des chaînes « CHAR », « CLOB », « STRI » ou « TEXT », cette colonne est alors d’affinité TEXT/STRING. Notez que le type VARCHAR contient la chaîne « CHAR » et possède donc l’affinité TEXT.

  • Si le type de données de la colonne contient la chaîne « BLOB » ou si aucun type de données n’est spécifié, l’affinité de la colonne est NONE.

  • Si le type de données de la colonne contient la chaîne « XMLL », l’affinité de la colonne est XMLList.

  • Si le type de données correspond à la chaîne « XML », l’affinité de la colonne est XML.

  • Si le type de données contient la chaîne « OBJE », l’affinité de la colonne est Object.

  • Si le type de données contient la chaîne « BOOL », l’affinité de la colonne est Boolean.

  • Si le type de données contient la chaîne « DATE», l’affinité de la colonne est Date.

  • Si le type de données contient la chaîne « INT» (y compris « UINT »), l’affinité de la colonne est INTEGER/int.

  • Si le type de données d’une colonne contient la chaîne « REAL », « NUMB », « FLOA » ou « DOUB », l’affinité de la colonne est REAL/Number.

  • Dans le cas contraire, l’affinité est NUMERIC.

  • Si une table est créée à l’aide d’une instruction CREATE TABLE t AS SELECT..., aucun type de données n’est spécifié pour les colonnes et l’affinité NONE leur est affectée.

Types de données et opérateurs de comparaison

Les opérateurs de comparaison binaires suivants, =, <, <=, >= et != sont pris en charge, ainsi qu’une opération permettant de tester l’appartenance, IN, et l’opérateur de comparaison ternaire BETWEEN. Pour plus d’informations sur ces opérateurs, voir Opérateurs.

Le résultat d’une comparaison dépend des classes de stockage des deux valeurs comparées. Lors de la comparaison de deux valeurs, les règles suivantes sont appliquées :

  • Une valeur dont la classe de stockage est NULL est considérée inférieure à toute autre valeur (y compris à une autre valeur dont la classe de stockage est NULL).

  • Une valeur INTEGER ou REAL est inférieure à toute valeur TEXT ou BLOB. Lorsqu’une valeur INTEGER ou REAL est comparée à une autre valeur INTEGER ou REAL, une comparaison numérique est effectuée.

  • Une valeur TEXT est inférieure à une valeur BLOB. Lorsque deux valeurs TEXT sont comparées, une comparaison binaire est effectuée.

  • Lorsque deux valeurs BLOB sont comparées, le résultat est toujours déterminé par une comparaison binaire.

L’opérateur ternaire BETWEEN est toujours remanié en tant qu’expression binaire équivalente. Par exemple, a BETWEEN b AND c est transformé en a >= b AND a <= c, même si cela signifie que des affinités différentes sont appliquées à a dans chacune des comparaisons requises pour évaluer l’expression.

Les expressions de type a IN (SELECT b ....) sont gérées selon les trois règles énumérées précédemment pour les comparaisons binaires, c’est-à-dire de la même façon que a = b. Par exemple, si b est une valeur de colonnes et a une expression, l’affinité de b est appliquée à a avant toute comparaison. L’expression a IN (x, y, z) est transformée en a = +x OR a = +y OR a = +z. Les valeurs situées à droite de l’opérateur IN (soit les valeurs x, y et z dans cet exemple) sont considérées comme des expressions, même s’il s’agit de valeurs de colonne. Si la valeur située à gauche de l’opérateur IN est une colonne, l’affinité de cette dernière est utilisée. Si la valeur est une expression, il ne se produit pas de conversion.

L’utilisation de la clause COLLATE peut également affecter la manière dont les comparaisons sont effectuées. Pour plus d’informations, voir COLLATE.

Types de données et opérateurs mathématiques

Pour chaque opérateur mathématique pris en charge (*, /, %, + et -), l’affinité numérique est appliquée à chaque opérande avant d’évaluer l’expression. S’il est impossible de convertir un opérande en classe de stockage NUMERIC, l’évaluation de l’expression donne le résultat NULL.

Si l’opérateur de concaténation || est utilisé, chaque opérande est converti en classe de stockage TEXT avant que l’expression ne soit évaluée. S’il est impossible de convertir un opérande en classe de stockage TEXT, le résultat de l’expression est NULL. Il peut s’avérer impossible de convertir la valeur dans deux cas de figure : soit la valeur de l’opérande est NULL, soit il s’agit d’un objet BLOB contenant une classe de stockage dont le type est autre que TEXT.

Types de données et tri

Lorsque les valeurs sont triées par une clause ORDER BY, les valeurs associées à la classe de stockage NULL sont prioritaires. Elles sont suivies des valeurs INTEGER et REAL classées par ordre numérique, suivies des valeurs TEXT classées par ordre binaire ou selon le classement spécifié (BINARY ou NOCASE). Les valeurs BLOB arrivent en dernière position, classées par ordre binaire. Il ne se produit pas de conversion des classes de stockage avant le tri.

Types de données et regroupement

Lors d’un regroupement des valeurs à l’aide de la clause GROUP BY, les valeurs associées à des classes de stockage différentes sont considérées comme distinctes. Les valeurs INTEGER et REAL font exception à la règle, car elles sont considérées comme égales si elles sont équivalentes d’un point de vue numérique. Aucune affinité n’est appliquée aux valeurs suite à l’exécution d’une clause GROUP BY.

Types de données et instructions SELECT composées

Les opérateurs SELECT composés (UNION, INTERSECT et EXCEPT) effectuent des comparaisons implicites entre les valeurs. Avant l’exécution de ces comparaisons, une affinité est susceptible d’être appliquée à chaque valeur. La même infinité est appliquée le cas échéant à toutes les valeurs pouvant être renvoyées dans une seule colonne du jeu de résultats SELECT composé. L’affinité appliquée correspond à l’affinité de la colonne renvoyée par la première instruction SELECT de composant dont une valeur de colonne (et non un autre type d’expression) occupe cette position. Si, pour une colonne SELECT composée donnée, aucune instruction SELECT de composant ne renvoie de valeur de colonne, aucune affinité n’est appliquée aux valeurs de cette colonne avant leur comparaison.