Suporte ao tipo de dados

Ao contrário da maioria dos bancos de dados SQL, o mecanismo SQL do Adobe AIR não exige ou impõe que essas colunas de tabela contenham valores de um determinado tipo. Na verdade, o tempo de execução usa dois conceitos, classes de armazenamento e afinidade de coluna, para controlar tipos de dados. Esta seção descreve as classes de armazenamento e a afinidade de coluna, bem como a forma com que as diferenças no tipo de dados são resolvidas em várias condições:

Classes de armazenamento

As classes de armazenamento representam os tipos de dados reais usados para armazenar valores em um banco de dados. As seguintes classes de armazenamento são usadas pelo banco de dados:

NULL
O valor é um valor NULL.

INTEGER
O valor é um inteiro assinado.

REAL
O valor é um número de ponto flutuante.

TEXT
O valor é uma string de texto (limitada a 256 MB).

BLOB
O valor é um BLOB (objeto binário grande); em outras palavras, dados binários brutos (limitados a 256 MB).

Todos os valores fornecidos ao banco de dados como literais incorporados em uma instrução SQL ou valores associados usando parâmetros a uma instrução SQL preparada são atribuídos a uma classe de armazenamento antes da execução da instrução SQL.

Os literais que fazem parte de uma instrução SQL são atribuídos à classe de armazenamento TEXT, caso estejam entre aspas simples ou duplas, INTEGER caso o literal seja especificado como um número sem aspas e casa decimal ou expoente, REAL caso o literal seja um número sem aspas com casa decimal ou expoente e NULL caso o valor seja NULL. Os literais com um BLOB da classe de armazenamento são especificados usando a notação X'ABCD'. Para obter mais informações, consulte Valores literais em expressões.

Valores fornecidos como parâmetros usando a matriz associativa SQLStatement.parameters são atribuídos à classe de armazenamento que mais corresponda ao tipo de dados nativos associado. Por exemplo, os valores int são associados como uma classe de armazenamento INTEGER, os valores Number recebem a classe de armazenamento REAL, os valores String recebem a classe de armazenamento TEXT e os objetos ByteArray recebem a classe de armazenamento BLOB.

Afinidade de coluna

A afinidade de uma coluna é o tipo recomendado para dados armazenados nessa coluna. Quando um valor é armazenado em uma coluna (por meio de uma instrução INSERT ou UPDATE), o tempo de execução tenta converter esse valor do tipo de dados na afinidade especificada. Por exemplo, caso um valor Date (uma ocorrência de Date em ActionScript ou JavaScript) seja inserido em uma coluna cuja afinidade é TEXT, o valor Date é convertido na representação String (equivalente à chamada do método toString() do objeto) antes do armazenamento no banco de dados. Caso o valor não possa ser convertido na afinidade especificada, ocorre um erro e a operação não é realizada. Quando um valor é recuperado do banco de dados usando uma instrução SELECT, ele é retornado como uma instância da classe correspondente à afinidade, independentemente de ser convertido de um tipo de dados diferente quando armazenado.

Caso uma coluna aceite valores NULL, o valor ActionScript ou JavaScript null pode ser usado como um valor de parâmetro para armazenar NULL na coluna. Quando um valor da classe de armazenamento NULL é recuperado em uma instrução SELECT, ele sempre é retornado como o valor de ActionScript ou JavaScript null, independentemente da afinidade da coluna. Caso uma coluna aceite valores NULL, sempre verifique valores recuperados da coluna para determinar se eles são null antes de tentar projetar os valores como um tipo que não possa ser nulo (como, por exemplo, Number ou Boolean).

Cada coluna do banco de dados é atribuída a uma das seguintes afinidades de tipo:

  • TEXT (ou String)

  • NUMERIC

  • INTEGER (ou int)

  • REAL (ou Number)

  • Booliano

  • Date

  • XML

  • XMLLIST

  • Objeto

  • NONE

TEXT (ou String)

Uma coluna com afinidade TEXT ou String armazena todos os dados que usam classes de armazenamento NULL, TEXT ou BLOB. Caso sejam inseridos dados numéricos em uma coluna com afinidade TEXT, eles são convertidos em forma de texto antes de serem armazenados.

NUMERIC

Uma coluna com afinidade NUMERIC contém valores que usam classes de armazenamento NULL, REAL ou INTEGER. Quando dados de texto são inseridos em uma coluna NUMERIC, é feita uma tentativa de convertê-los em um inteiro ou número real antes de serem armazenados. Caso haja êxito na conversão, o valor é armazenado usando a classe de armazenamento INTEGER ou REAL (por exemplo, um valor igual a '10.05' é convertido na classe de armazenamento REAL antes de ser armazenado). Caso a conversão não possa ser realizada, ocorre um erro. não é feita nenhuma tentativa de converter um valor NULL. Um valor recuperado de uma coluna NUMERIC é retornado como uma ocorrência do tipo numérico mais específico no qual o valor se encaixa. Em outras palavras, caso o valor seja um inteiro positivo ou 0, ele é retornado como uma ocorrência de unit. Caso seja um inteiro negativo, ele é retornado como uma ocorrência de int. Por fim, caso tenha um componente de ponto flutuante (não um inteiro), ele é retornado como uma instância de Number.

INTEGER (ou int)

Uma coluna que usa afinidade INTEGER se comporta da mesma forma que uma coluna com afinidade NUMERIC, exceto por uma coisa. Caso o valor a ser armazenado seja um valor real (como, por exemplo, uma instância de Number) sem nenhum componente de ponto flutuante ou caso o valor seja um valor de texto que possa ser convertido em um valor real sem nenhum componente de ponto flutuante, ele é convertido em um inteiro e armazenado usando a classe de armazenamento INTEGER. Caso seja feita uma tentativa de armazenar um valor real com um componente de ponto flutuante, ocorre um erro.

REAL (ou Number)

Uma coluna com afinidade REAL ou NUMBER se comporta como uma coluna com afinidade NUMERIC, exceto pelo fato de forçar valores inteiros na representação de ponto flutuante. Um valor em uma coluna REAL é sempre retornado do banco de dados como uma instância de Number.

Booliano

Uma coluna com afinidade Boolean armazena valores true ou false. Uma coluna Boolean aceita um valor que é uma ocorrência de Boolean em ActionScript ou JavaScript. Caso o código tente armazenar um valor String, String com comprimento maior que zero é considerada verdadeira e uma String vazia, falsa. Caso o código tente armazenar dados numéricos, qualquer valor que não seja zero é armazenado como true e 0, como false. Quando um valor Boolean é recuperado usando uma instrução SELECT, ele é retornado como uma ocorrência de Boolean. Valores que não sejam NULL são armazenados usando a classe de armazenamento INTEGER (0 para false e 1 para true), sendo convertidos em objetos Boolean quando os dados são recuperados.

Date

Uma coluna com afinidade Date armazena valores de data e hora. Uma coluna Date é projetada para aceitar valores que sejam ocorrências de Date em ActionScript ou JavaScript. Caso seja feita uma tentativa de armazenar um valor String em uma coluna Date, o tempo de execução tenta convertê-lo em uma data do calendário Juliano. Em caso de falha na conversão, ocorre um erro. Caso o código tente armazenar um valor de Number, int ou uint, não é feita nenhuma tentativa de validar os dados, pressupondo que ele seja um valor de data do calendário Juliano válido. Um valor Date recuperado usando uma instrução SELECT é convertido automaticamente em uma ocorrência de Date. Como os valores de Date são armazenados como valores de data do calendário Juliano usando a classe de armazenamento REAL, as operações de classificação e comparação funcionam da forma como você espera.

XML ou XMLList

Uma coluna que usa afinidade XML ou XMLList armazena estruturas XML. Quando o código tenta armazenar dados em uma coluna XML usando um parâmetro SQLStatement, o tempo de execução tenta converter e validar o valor usando a função XML() ou XMLList() em ActionScript. Caso o valor não possa ser convertido em um XML válido, ocorre um erro. Caso a tentativa de armazenar os dados use um valor de texto SQL literal (por exemplo, INSERT INTO (col1) VALUES ('Invalid XML (no closing tag)'), o valor não é analisado ou validado — pressupõe-se que esteja bem-formado. Caso um valor inválido seja armazenado, quando recuperado, ele é retornado como um objeto XML vazio. Dados XML e XMLList são armazenados usando a classe de armazenamento TEXT ou NULL.

Objeto

Uma coluna com afinidade Object armazena objetos complexos em ActionScript ou JavaScript, inclusive ocorrências da classe Object, bem como ocorrências das subclasses de Object como, por exemplo, ocorrências de Array e até mesmo ocorrências de classe personalizada. Os dados da coluna Object são serializados no formato AMF3 e armazenados usando a classe de armazenamento BLOB. Quando recuperado, um valor é desserializado do AMF3 e retornado como uma instância da classe como foi armazenado. Observe que algumas classes ActionScript, mais notadamente objetos de exibição, não podem ser desserializadas como ocorrências do tipo de dados original. Antes de armazenar uma ocorrência de classe personalizada, você deve registrar um alias para a classe usando o método flash.net.registerClassAlias() (ou em Flex, adicionando metadados [RemoteObject] à declaração da classe). Além disso, antes de recuperar esses dados, você deve registrar o mesmo alias para a classe. Qualquer dado que não possa ser serializado corretamente porque a classe não pode ser desserializada inerentemente ou por conta de um alias de classe ausente ou não correspondente é retornado como um objeto anônimo (uma ocorrência de classe Object) com propriedades e valores correspondentes à ocorrência original de acordo com o armazenamento.

NONE

Uma coluna com afinidade NONE não prefere nenhuma classe de armazenamento em detrimento de outra. Ela não faz nenhuma tentativa de converter dados antes de serem inseridos.

Determinação da afinidade

A afinidade de tipo de uma coluna é determinada pelo tipo declarativo da coluna na instrução CREATE TABLE. Quando o tipo é determinado, as seguintes regras (sem distinção de caixa) se aplicam:

  • Caso o tipo de dados da coluna contenha uma das strings CHAR, CLOB, STRI, ou TEXT essa coluna terá afinidade com TEXT/String. Observe que o tipo VARCHAR contém a string CHAR e, por isso, é atribuído à afinidade TEXT.

  • Caso o tipo de dados da coluna contenha a string BLOB ou caso nenhum tipo de dados seja especificado, a afinidade da coluna é NONE.

  • Caso o tipo de dados da coluna contenha a string XMLL, a coluna tem afinidade XMLList.

  • Caso o tipo de dados seja a string XML, a coluna tem afinidade XML.

  • Caso o tipo de dados contenha a string OBJE, a coluna tem afinidade Object.

  • Caso o tipo de dados contenha a string BOOL, a coluna tem afinidade Boolean.

  • Caso o tipo de dados contenha a string DATE, a coluna tem afinidade Date.

  • Caso o tipo de dados contenha a string INT (inclusive UINT), ele é atribuído à afinidade INTEGER/int.

  • Caso o tipo de dados da coluna contenha uma das strings REAL, NUMB, FLOA ou DOUBa coluna apresenta afinidade REAL/Number.

  • Do contrário, a afinidade é NUMERIC.

  • Caso uma tabela seja criada usando uma instrução CREATE TABLE t AS SELECT..., todas as colunas não têm nenhum tipo de dados especificado, sendo todas atribuídas à afinidade NONE.

Tipos de dados e operadores de comparação

Há suporte para estes operadores de comparação binária =, <, <=, >= e !=, além de uma operação para testar a associação do conjunto, IN e operador de comparação ternário BETWEEN. Para obter detalhes sobre esses operadores, consulte Operadores.

Os resultados de uma comparação dependem das classes de armazenamento dos dois valores que estão sendo comparados. Durante a comparação entre duas regras, se aplicam as seguintes regras:

  • Um valor com classe de armazenamento NULL é considerado inferior a qualquer outro valor (inclusive outro valor com classe de armazenamento NULL).

  • Um valor INTEGER ou REAL é inferior a qualquer valor TEXT ou BLOB. Quando INTEGER ou REAL é comparado com outro INTEGER ou REAL, é realizada uma comparação numérica.

  • Um valor TEXT é inferior a um valor BLOB. Quando dois valores TEXT são comparados, é realizada uma comparação binária.

  • Quando dois valores BLOB são comparados, o resultado é sempre determinado usando uma comparação binária.

O operador ternário BETWEEN é sempre reprojetado como a expressão binária equivalente. Por exemplo, a BETWEEN b AND c é reprojetado como a >= b AND a <= c, mesmo que isso signifique a aplicação de afinidades diferentes a a em cada uma das comparações necessárias à avaliação da expressão.

Expressões do tipo a IN (SELECT b ....) são tratadas pelas três regras enumeradas anteriormente para as comparações binárias, ou seja, de maneira semelhante a a = b. Por exemplo, caso b seja um valor de coluna e a seja uma expressão, a afinidade b é aplicada a a antes da realização de qualquer outra comparação. A expressão a IN (x, y, z) é reprojetada como a = +x OR a = +y OR a = +z. Os valores à direita do operador IN (os valores x, y e z nesse exemplo) são considerados expressões, mesmo que sejam valores de coluna. Caso o valor à esquerda do operador IN seja uma coluna, é usada a afinidade dessa coluna. Caso o valor seja uma expressão, não ocorre nenhuma conversão.

A forma como as comparações são realizadas também pode ser afetada pelo uso de uma cláusula COLLATE. Para obter mais informações, consulte COLLATE.

Tipos de dados e operadores matemáticos

Para cada um dos operadores matemáticos para os quais há suporte, *, /, %, + e -, a afinidade numérica é aplicada a cada operando antes da avaliação da expressão. Caso nenhum operando possa ser convertido na classe de armazenamento NUMERIC com êxito, a expressão é avaliada como NULL.

Quando o operador de concatenação || é usado, cada operando é convertido na classe de armazenamento TEXT antes da avaliação da expressão. Caso nenhum operando possa ser convertido na classe de armazenamento TEXT, o resultado da expressão é NULL. A impossibilidade de conversão do valor pode acontecer em duas situações: caso o valor do operando seja NULL ou caso ele seja um BLOB que contenha uma classe de armazenamento que não seja TEXT.

Tipos de dados e classificação

Quando os valores são classificados por uma cláusula ORDER BY, os valores com uma classe de armazenamento NULL vêm primeiro. Eles são seguidos dos valores INTEGER e REAL dispostos em ordem numérica, seguidos dos valores TEXT em ordem binária ou com base na intercalação especificada (BINARY ou NOCASE). Por fim, vêm os valores BLOB na ordem binária. não ocorre nenhuma conversão de classe antes da classificação.

Tipos de dados e agrupamento

Durante o agrupamento de valores com a cláusula GROUP BY, valores com classes de armazenamento diferentes são consideradas distintas. Uma exceção a isso são os valores INTEGER e REAL, que são considerados iguais caso sejam numericamente equivalentes. Nenhuma afinidade é aplicada a nenhum valor por conta de uma cláusula GROUP BY.

Tipos de dados e instruções SELECT compostas

Os operadores SELECT compostos UNION, INTERSECT e EXCEPT realizam comparações implícitas entre valores. Para que essas comparações sejam realizadas, uma afinidade pode ser aplicada a cada valor. A mesma afinidade, caso haja alguma, é aplicada a todos os valores que podem ser retornados em uma única coluna do conjunto de resultados SELECT. A afinidade aplicada é a afinidade da coluna retornada pela instrução SELECT do primeiro componente que apresenta um valor de coluna (e não outro tipo de expressão) nessa posição. Se, para uma determinada coluna SELECT composta, nenhuma das instruções SELECT do componente retornem um valor de coluna, nenhuma afinidade será aplicada aos valores dessa coluna antes de serem comparados.