Fonctions supplémentaires pour le support des fuseaux horaires
Firebird 4 offre un certain nombre de fonctionnalités pour les informations sur les fuseaux horaires.
Types numériques approximatifs
Comportement des opérations avec DECFLOAT
Longueur des littéraux DECFLOAT
DECFLOAT et fonctions Utilisation des fonctions conventionnelles Fonctions spéciales pour `DECFLOAT
Types de données en virgule flottante
Types de données à virgule fixe
Types de données pour travailler avec la date et l'heure
Conversion des types de données
Firebird 4 offre un certain nombre de fonctionnalités pour les informations sur les fuseaux horaires.
RDB$TIME_ZONES
Une table virtuelle avec une liste des fuseaux horaires supportés par Firebird.
Voir aussi RDB$TIME_ZONES
dans l’annexe "Tableaux du système".
RDB$TIME_ZONE_UTIL
Le paquet RDB$TIME_ZONE_UTIL
contient des procédures et des fonctions pour travailler avec les fuseaux horaires.
Vous trouverez une description détaillée du paquetage dans la section RDB$TIME_ZONE_UTIL
du chapitre Paquetages système.
Les fuseaux horaires changent fréquemment : bien entendu, lorsque cela se produit, il est conseillé de mettre à jour la base de données des fuseaux horaires dès que possible.
Firebird stocke les valeurs `WITH TIME ZONE' traduites en heure UTC. Supposons qu’une valeur soit créée en utilisant une base de données de fuseaux horaires et qu’une mise à jour ultérieure de cette base de données modifie les informations dans la plage de notre valeur stockée. Lorsque cette valeur est lue, elle sera renvoyée comme étant différente de la valeur qui était stockée à l’origine.
Firebird utilise IANA base de données des fuseaux horaires via la bibliothèque de l’ICU. La bibliothèque ICU fournie avec Firebird (Windows) ou installée dans un système d’exploitation POSIX peut parfois avoir une base de données de fuseaux horaires obsolète.
La base de données mise à jour peut être consultée à l’adresse suivante sur cette page du GitHub de FirebirdSQL.Le nom de fichier le.zip
désigne un ordre d’octet direct et est un fichier requis pour la plupart des architectures informatiques (compatibles Intel/AMD x86 ou x64), tandis que be.zip
désigne un ordre d’octet direct et est requis principalement pour les architectures informatiques RISC.Le contenu du fichier zip doit être extrait dans le sous-répertoire /tzdata
de l’installation Firebird, en écrasant les fichiers *.res
existants.
Note
|
|
Firebird possède des types CHAR
de longueur fixe et VARCHAR
de longueur variable pour gérer les données de type caractère.La taille maximale des données texte stockées dans ces types de données est de 32767 octets pour CHAR
et 32765 octets pour VARCHAR
.Le nombre maximum de caractères pouvant tenir dans cette taille dépend du jeu de caractères CHARACTER SET' utilisé.La séquence de tri spécifiée par la clause `COLLATE
n’a aucun effet sur ce maximum, bien qu’elle puisse affecter la taille maximale de tout index qui inclut une colonne.
Si aucun jeu de caractères n’est explicitement spécifié, le jeu de caractères par défaut spécifié lors de la création de l’objet texte de la base de données sera utilisé lors de la description de l’objet texte de la base de données.Si aucun jeu de caractères n’est explicitement spécifié et qu’il n’existe pas de jeu de caractères par défaut pour la base de données, le champ reçoit le jeu de caractères `CHARACTER SET NONE'.
Actuellement, tous les outils de développement modernes prennent en charge Unicode.Si vous devez utiliser des textes d’Europe de l’Est dans des champs de chaîne de données ou pour des alphabets plus exotiques, il est recommandé de travailler avec le jeu de caractères UTF8.Notez qu’il y a jusqu’à 4 octets par caractère dans ce jeu de caractères.Par conséquent, le nombre maximal de caractères dans les champs de caractères sera de 32765/4 = 8191.
Note
|
Notez que la valeur réelle du paramètre "octets par caractère" dépend de la gamme à laquelle appartient le caractère : les lettres anglaises prennent 1 octet, les lettres russes prennent 2 octets, les autres caractères peuvent prendre jusqu’à 4 octets. |
Le jeu de caractères UTF8 supporte la dernière version de la norme Unicode, jusqu’à 4 octets par caractère. Pour les bases de données internationales, il est donc recommandé d’utiliser cette implémentation du support Unicode dans Firebird.
NCHAR
Représente un type de données de caractères de longueur fixe avec un jeu de caractères ISO8859_1 prédéfini.
{NCHAR | NATIONAL {CHAR | CHARACTER}} [(length)]
Un synonyme est d’écrire CHAR NATIONAL
.
Un type de données similaire est disponible pour un type de chaîne de longueur variable : NATIONAL CHARACTER VARYING
.
Lorsqu’on traite des chaînes de caractères, il est important de se souvenir du jeu de caractères de la connexion client.Si le jeu de caractères est différent, la sortie des colonnes de chaînes de caractères est automatiquement recodée, à la fois lors du transfert des données du client vers le serveur, et dans le sens inverse, du serveur vers le client.En d’autres termes, il est parfaitement normal qu’une base de données soit créée avec le codage WIN1251
et que le client ait KOI8R
ou UTF8
dans les paramètres de connexion.
Le jeu de caractères `NONE' fait référence aux jeux de caractères spéciaux.Il se caractérise par le fait que chaque octet fait partie d’une chaîne de caractères, mais est stocké dans le système sans aucune indication du jeu de caractères auquel il appartient.C’est à l’application cliente de traiter ces données et il lui incombe d’interpréter correctement les caractères de ces champs.
Les jeux de caractères spéciaux comprennent également les `OCTETS'.Dans ce cas, les données sont traitées comme des octets, qui peuvent en principe ne pas être interprétés comme des caractères.`OCTETS' permet de stocker des données binaires et/ou les résultats de certaines fonctions Firebird.L’affichage correct des données stockées dans les champs `CHARACTER SET OCTETS' pour l’utilisateur devient également une préoccupation du côté client.Lorsque vous travaillez avec de telles données, n’oubliez pas que le SGBD n’a aucun contrôle sur leur contenu et qu’une exception peut être levée lorsque le code tente d’afficher des données binaires dans l’encodage souhaité.
Chaque jeu de caractères possède une séquence de tri (correspondance) par défaut (COLLATE
) qui détermine l’ordre de correspondance. Normalement, il assure un tri basé sur le code numérique des caractères et une correspondance de base entre les caractères majuscules et minuscules. Si un comportement est requis pour les chaînes de caractères qui n’est pas fourni par la séquence de tri par défaut, et qu’un tri alternatif approprié est supporté pour ce jeu de caractères, la clause COLLATE collation
peut être spécifiée dans la définition de la colonne.
La phrase COLLATE collation
peut être utilisée dans des contextes autres que la définition de la colonne. Pour les opérations de comparaison plus/moins, il peut être ajouté à la clause WHERE
de l’opérateur SELECT
. Si la sortie doit être triée dans une séquence alphabétique spécifique ou sans tenir compte de la casse et qu’il existe une correspondance appropriée, la phrase COLLATE
peut être utilisée dans la phrase ORDER BY
lorsque les lignes sont triées par champ de caractères, et dans la phrase GROUP BY
dans le cas d’opérations de groupe.
Pour une recherche insensible à la casse, vous pouvez utiliser la fonction UPPER
.
Pour une recherche insensible à la casse, vous pouvez utiliser la fonction UPPER
pour convertir l’argument de recherche et l’argumentet les chaînes de caractères recherchées en majuscules avant de tenter une correspondance.
...
WHERE UPPER(name) = UPPER(:flt_name)
Pour les chaînes de caractères dans un jeu de caractères pour lequel le tri insensible à la casse est disponible, vous pouvez simplement appliquerpour comparer directement l’argument de recherche et les chaînes de caractères.Par exemple, si vous utilisez le jeu de caractères WIN1251
, vous pouvez utiliser le tri insensible à la casse PXW_CYRL
à cette fin.
...
WHERE FIRST_NAME COLLATE PXW_CYRL >= :FLT_NAME
...
ORDER BY NAME COLLATE PXW_CYRL
Vous trouverez ci-dessous un tableau des séquences de tri possibles pour le jeu de caractères UTF8.
COLLATION | Commentaire |
---|---|
UCS_BASIC |
Le tri s’effectue en fonction de la position du caractère dans l’ordre alphabétique.table (binaire). |
UNICODE |
Le tri s’effectue selon l’algorithme UCA.(Unicode Collation Algorithm) (alphabétique). |
UTF-8 |
Par défaut, un mappage binaire est utilisé,identique à UCS_BASIC, qui a été ajouté pour les raisons suivantesla compatibilité avec la norme SQL. |
UNICODE_CI |
Triage sans tenir compte de la casse des caractères. |
UNICODE_CI_AI |
Triage sans casse et sans signes diacritiquespar ordre alphabétique. |
Exemple de tri de chaînes de caractères pour le jeu de caractères UTF8 sans caractères sensibles à la casse et sans diacritiques.
ORDER BY NAME COLLATE UNICODE_CI_AI
Lorsque l’on construit un index basé sur des champs de type chaîne, il faut tenir compte d’une restriction sur la longueur de la clé d’indexation.La longueur maximale de la clé d’indexation utilisée est égale à 1/4 de la taille de la page, c’est-à-dire de 1024 (pour une taille de page de 4096) à 8192 octets (pour une taille de page de 32768). La longueur maximale de la chaîne d’index est inférieure de 9 octets à la longueur maximale de la clé.Le tableau indique la longueur maximale de la chaîne d’index (en caractères) en fonction du format de la page et du jeu de caractères. Elle peut être calculée à l’aide de la formule suivante :
max_char_length = FLOOR((page_size / 4 – 9) / N),
où N
— nombre d’octets par représentation de caractère.
Taille de la page |
Longueur maximale dechaîne indexée pour le jeu de caractères, octet/symbole |
||||
---|---|---|---|---|---|
1 |
2 |
3 |
4 |
6 |
|
4096 |
1015 |
507 |
338 |
253 |
169 |
8192 |
2039 |
1019 |
679 |
509 |
339 |
16384 |
4087 |
2043 |
1362 |
1021 |
681 |
32768 |
8183 |
4091 |
2727 |
2045 |
1363 |
Note
|
Dans les codages insensibles à la casse ("`_CI"), un caractère dans l'index prendra 6 octets au lieu de 4, de sorte que la longueur maximale de la clé pour une page, par exemple pour une page de 4096 octets, est de 169 caractères. |
La séquence de tri (COLLATE) peut également affecter la longueur maximale d’une chaîne indexée.Une liste complète des jeux de caractères disponibles et des ordres de tri non standard est disponible en annexe.Jeux de caractères et ordres de tri.
CREATE DATABASE
, Ordre de tri, SELECT
, WHERE
, GROUP BY
, ORDER BY
BINARY
BINARY
est un type de données de longueur fixe permettant de stocker des données binaires.Si le nombre d’octets transférés est inférieur à la longueur déclarée, la valeur sera complétée par des zéros.Si aucune longueur n’est spécifiée, on suppose qu’elle est égale à un.
BINARY [(<length>)]
Note
|
Ce type est un alias du type `CHAR [(<length>)] CHARACTER SET OCTETS' et est rétrocompatible avec celui-ci. |
Tip
|
Ce type est bien adapté au stockage d’un identifiant unique obtenu à l’aide de la fonction [fblangref-scalarfuncs-gen-uuid]. |
CHAR
CHAR
est un type de données de longueur fixe.Si le nombre de caractères saisis est inférieur à la longueur déclarée, le champ sera complété par des espaces de fin.En général, le caractère de remplacement peut ne pas être un espace, cela dépend du jeu de caractères, par exemple, pour un jeu de caractères OCTETS
, c’est zéro.
Le nom complet du type de données est CHARACTER
, mais il n’est pas nécessaire d’utiliser les noms complets lorsqu’on travaille avec lui ; les outils de base de données comprennent très bien les noms courts des types de données caractères.
{CHAR | CHARACTER} [(length)] [CHARACTER SET <charset>] [COLLATE <collate>]
Si aucune longueur n’est spécifiée, on suppose qu’elle est égale à un.
Ce type de données de caractères peut être utilisé pour stocker des codes dans des répertoires dont la longueur est standard et d’une certaine "largeur".Un exemple de ceci serait un code postal en Russie - 6 caractères.
VARBINARY
VARBINARY
est un type permettant de stocker des données binaires de longueur variable.La taille réelle de la structure stockée est égale à la taille réelle des données plus les 2 octets dans lesquels la longueur du champ est spécifiée.
Nom complet BINARY VARYING
.
{VARBINARY | BINARY VARYING} (<length>)
Note
|
Ce type est un alias du type `VARCHAR (<length>) CHARACTER SET OCTETS' et est rétrocompatible avec celui-ci. |
DECLARE VARIABLE VAR1 VARBINARY(10);
CREATE TABLE INFO (
GUID BINARY(16),
ENCRYPT_KEY VARBINARY(100),
ICON BINARY VARYING(32000));
VARCHAR
VARCHAR
est un type de chaîne de base permettant de stocker des textes de longueur variable. La taille réelle de la structure stockée est donc égale à la taille réelle des données plus les 2 octets dans lesquels la longueur du champ est spécifiée.
Tous les caractères qui sont transmis de l’application client à la base de données sont traités comme des caractères significatifs, y compris les espaces de début et de fin.
Nom complet CHARACTER VARYING
.Une version abrégée de l’article est également disponible. CHAR VARYING
.
{VARCHAR | {CHAR | CHARACTER} VARYING} (length) [CHARACTER SET <charset>] [COLLATE <collate>]
Dans Firebird 3.0, un type de données logique complet a été introduit.
BOOLEAN
Le type de données BOOLEAN
(8 bits) conforme à SQL-2008 comprend diverses valeurs de vérité TRUE
et FALSE
.À moins que la restriction NOT NULL
ne soit définie, le type de données BOOLEAN
supporte également la valeur de vérité UNKNOWN
comme une valeur NULL
.La spécification ne fait pas de distinction entre une valeur NULL de ce type et une valeur de vérité UNKNOWN qui est le résultat d’un prédicat SQL, d’une condition de recherche ou d’une expression de type logique.Ces valeurs sont interchangeables et signifient la même chose.
Comme dans les autres langages de programmation, les valeurs de type BOOLEAN
peuvent être testées en valeurs de vérité implicites.Par exemple, "champ1 OR champ2" ou "NOT champ1" sont des expressions valables.
IS
Les prédicats peuvent utiliser l’opérateur logical IS [NOT]
pour la correspondance.Par exemple, field1 IS FALSE
, ou field1 IS NOT TRUE
.
Note
|
|
BOOLEAN
CREATE TABLE TBOOL (ID INT, BVAL BOOLEAN);
COMMIT;
INSERT INTO TBOOL VALUES (1, TRUE);
INSERT INTO TBOOL VALUES (2, 2 = 4);
INSERT INTO TBOOL VALUES (3, NULL = 1);
COMMIT;
SELECT * FROM TBOOL
ID BVAL ============ ======= 1 <true> 2 <false> 3 <null>
SELECT * FROM TBOOL WHERE BVAL
ID BVAL ============ ======= 1 <true>
FALSE
.SELECT * FROM TBOOL WHERE BVAL IS FALSE
ID BVAL ============ ======= 2 <false>
UNKNOWN
.SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN
ID BVAL ============ ======= 3 <null>
SELECT ID, BVAL, BVAL AND ID < 2
FROM TBOOL
ID BVAL ============ ======= ======= 1 <true> <true> 2 <false> <false> 3 <null> <false>
DECLARE VARIABLE VAR1 BOOLEAN = TRUE;
-- Syntaxe acceptable, mais comme la comparaison
-- NULL, ne renverra jamais aucun des enregistrements
SELECT * FROM TBOOL WHERE BVAL = UNKNOWN
SELECT * FROM TBOOL WHERE BVAL <> UNKNOWN
Bien que BOOLEAN
ne puisse pas être converti en un autre type de données, à partir de la version 3.0.1, les chaînes 'true'
et 'false'
(insensibles à la casse) seront implicitement converties en BOOLEAN
dans les expressions de valeurs, par exemple
if (true > 'false') then ...
'False'
est converti en BOOLEAN
.Toute tentative d’utiliser les opérateurs logiques AND
, NOT
, OR
et IS
échouera.Par exemple, NOT 'False'
provoquera une erreur.
Un BOOLEAN
peut être explicitement converti en et depuis une chaîne de caractères en utilisant CAST
.La valeur UNKNOWN
n’est pas disponible lors de la conversion en chaîne.
Note
|
Autres remarques
|
BLOB
Les BLOB (Binary Large Objects) sont des structures complexes conçues pour stocker des données textuelles et binaires de longueur indéfinie, souvent de très grande taille.
BLOB [SUB_TYPE <subtype>] [SEGMENT SIZE <seg_length>] [CHARACTER SET <charset>] [COLLATE <collation name>]
BLOB (<seg_length>) BLOB (<seg_length>, <subtype>) BLOB (, <subtype>)
La spécification d’une taille de segment BLOB est en quelque sorte un atavisme, qui remonte à l’époque où les applications destinées à travailler avec des données BLOB étaient écrites en C (Embedded SQL) à l’aide de GPRE.Actuellement, la taille du segment lors de l’utilisation de données BLOB est déterminée par la partie client, et la taille du segment peut dépasser la taille de la page de données.
Le sous-type BLOB reflète la nature des données enregistrées dans la colonne.Firebird fournit deux sous-types prédéfinis pour le stockage des données utilisateur :
Si aucun sous-type n’est spécifié, les données sont considérées comme non typées et la valeur du sous-type est supposée être 0.L’alias du sous-type 0 est BINARY
.Ce sous-type indique que les données se présentent sous la forme d’un fichier ou d’un flux binaire (image, son, vidéo, fichiers de traitement de texte, PDF, etc.)
Le sous-type 1 a un alias TEXT
, qui peut être utilisé au lieu de spécifier un numéro de sous-type.Par exemple, BLOB SUBTYPE TEXT
.Il s’agit d’un sous-type spécialisé qui est utilisé pour stocker des données textuelles de grande taille.Pour le sous-type de texte BLOB
, un jeu de caractères et un ordre de tri COLLATE
peuvent être spécifiés, comme pour un champ de caractères.
Il est également possible d’ajouter des sous-types de données personnalisés, pour lesquels un intervalle de -1 à -32768 est réservé.Les sous-types personnalisés avec des nombres positifs ne sont pas supportés car Firebird utilise des nombres supérieurs à 2 pour les sous-types de métadonnées internes.
La taille maximale du champ BLOB est limitée à 4 Go et ne dépend pas de la variante du serveur, 32 bits ou 64 bits (il existe des compteurs de 4 octets dans les structures internes liées aux BLOB). Pour une taille de page de 4096, la taille maximale du champ BLOB est légèrement inférieure à 2 Go.
Les BLOB texte de n’importe quelle longueur et avec n’importe quel jeu de caractères (y compris multi-octets) peuvent être utilisés avec presque toutes les fonctions et opérateurs intégrés.
Les opérateurs suivants sont entièrement pris en charge :
= |
(affectation) |
=, <>, <, <=, >, >= |
(comparaison) |
|
(concaténation) |
|
|
|
|
|
|
Les opérateurs suivants sont partiellement pris en charge :
Une erreur se produit si le second argument est supérieur ou égal à 32Kb.
|
|
|
|
Les suggestions d’agrégation ne fonctionnent pas avec le contenu du champ lui-même, mais avec l’ID BLOB. En dehors de cela, il y a quelques bizarreries :
|
produit par erreur des valeurs NULL multiples si elles sont présentes |
|
— |
|
fusionne les mêmes lignes si elles sont adjacentes l’une à l’autre, mais ne le fait pas si elles sont éloignées l’une de l’autre |
Par défaut, un enregistrement régulier est créé pour chaque BLOB
stocké sur une page de données dédiée (page de données). Si un BLOB entier tient sur cette page, on l’appelle un `BLOB' de niveau 0. Le numéro de cet enregistrement spécial est stocké dans l’enregistrement de la table et occupe 8 octets.
Si BLOB
ne tient pas sur une seule page de données (data page), son contenu est placé sur des pages séparées entièrement allouées pour lui (blob page), et les numéros de ces pages sont placés dans l’enregistrement de BLOB
. Il s’agit d’une BLOB
de niveau 1.
Si un tableau de numéros de pages de données d’un BLOB
ne tient pas sur une page de données, alors il est placé sur des pages séparées (blob pages) et l’enregistrement d’un BLOB
contient les numéros de ces pages. Il s’agit d’un `BLOB' de niveau 2.
Les niveaux supérieurs à 2 ne sont pas pris en charge.
Le support des tableaux dans Firebird est une extension du modèle relationnel traditionnel.La prise en charge des tableaux est une extension du modèle relationnel traditionnel.Les tableaux dans Firebird sont basés sur des champs BLOB.Les tableaux peuvent être unidimensionnels ou multidimensionnels.
CREATE TABLE SAMPLE_ARR (
ID INTEGER NOT NULL PRIMARY KEY,
ARR_INT INTEGER [4]);
Cela créera une table avec un champ de type tableau de quatre entiers.Les indices de ce tableau sont de 1 à 4.
Par défaut, les dimensions commencent à 1.La syntaxe suivante doit être utilisée pour définir la limite supérieure et inférieure des valeurs d’index :
[<lower>:<upper>]
L’ajout d’une nouvelle dimension dans la syntaxe se fait avec une virgule.Un exemple de création d’une table avec un tableau de dimension deux, où la limite inférieure des valeurs commence par zéro :
CREATE TABLE SAMPLE_ARR2 (
ID INTEGER NOT NULL PRIMARY KEY,
ARR_INT INTEGER [0:3, 0:3]);
Le SGBDR ne fournit pas beaucoup d’outils pour manipuler le contenu des tableaux.La base de données employee.fdb, qui se trouve dans la distribution Firebird, contient un exemple de procédure stockée qui montre comment manipuler des tableaux.Voici le texte de la procédure stockée :
CREATE OR ALTER PROCEDURE SHOW_LANGS (
CODE VARCHAR(5),
GRADE SMALLINT,
CTY VARCHAR(15))
RETURNS (
LANGUAGES VARCHAR(15))
AS
DECLARE VARIABLE I INTEGER;
BEGIN
I = 1;
WHILE (I <= 5) DO
BEGIN
SELECT LANGUAGE_REQ[:I]
FROM JOB
WHERE (JOB_CODE = :CODE)
AND (JOB_GRADE = :GRADE)
AND (JOB_COUNTRY = :CTY)
AND (LANGUAGE_REQ IS NOT NULL))
INTO :LANGUAGES;
IF (:LANGUAGES = '') THEN
/* IMPRIME 'NULL' AU LIEU DE BLANCS */
LANGUAGES = 'NULL';
I = I +1;
SUSPEND;
END
END
Si les caractéristiques ci-dessus sont suffisantes pour vos besoins, vous pouvez très bien utiliser les tableaux pour vos projets.Il n’y a actuellement aucune amélioration dans les mécanismes de gestion des tableaux du SGBD.
SQL_NULL
Ce type de données ne contient pas de données, mais seulement un état : NULL
ou NOT NULL
.De plus, ce type de données ne peut pas être utilisé lors de la déclaration de champs de table, de variables PSQL, utilisés dans les descriptions de paramètres.Ce type de données a été ajouté pour améliorer la prise en charge des paramètres non typés dans le prédicat IS NULL
.Ce problème se produit lors de l’utilisation de filtres excluables
lors de l’écriture de requêtes du type suivant :
WHERE col1 = :param1 OR :param1 IS NULL
Une fois traitée, au niveau de l’API, la demande aura l’apparence suivant
WHERE col1 = ? OR ? IS NULL
Dans ce cas, le développeur traite :param1
comme une variable qui est utilisée deux fois, alors qu’au niveau de l’API, la requête contient deux paramètres distincts et indépendants.En plus de cela, le serveur ne peut pas déterminer le type du second paramètre car il est associé à IS NULL
.
C’est pour résoudre le ` ? IS NULL` a été ajouté ce type de données spécial SQL_NULL.
Après l’introduction de ce type de données spécial, lors de l’envoi d’une requête et de ses paramètres au serveur, le schéma suivant sera appliqué : l’application transmet les requêtes paramétrées au serveur sous la forme “?”.Il est donc impossible de fusionner une paire de paramètres "identiques" en un seul.Ainsi, par exemple, pour deux filtres (deux paramètres nommés), quatre paramètres positionnels doivent être passés (en supposant en outre que le lecteur a une certaine familiarité avec l’API de Firebird) :
SELECT
SH.SIZE, SH.COLOUR, SH.PRICE
FROM SHIRTS SH
WHERE (SH.SIZE = ? OR ? IS NULL)
AND (SH.COLOUR = ? OR ? IS NULL)
Après l’exécution de isc_dsql_describe_bind()
, le sqltype des 2ème et 4ème paramètres est défini comme SQL_NULL.Comme indiqué ci-dessus, le serveur Firebird ne dispose d’aucune information sur leur relation avec les 1er et 3ème paramètres — c’est entièrement la prérogative du programmeur.Une fois que les valeurs des 1er et 3e paramètres ont été définies (ou mises à NULL) et que la requête est préparée, chaque paire de XSQLVARs doit être remplie comme suit :
Premier paramètre (comparaison de valeurs) : définition de *sqldata
à la valeur passée et de *sqlind
à 0
(pour NOT NULL
) ;
Deuxième paramètre (vérification de NULL) : mettre *sqldata
à null
(pointeur nul, pas SQL NULL
) et *sqlind
à 0 (pour NOT NULL
).
Les deux paramètres (vérification de NULL) : mettre *sqldata
à null
(pointeur nul, pas SQL NULL
) et *sqlind
à -1 (indication NULL
).
En d’autres termes, la valeur du paramètre de comparaison est toujours fixée comme d’habitude.Le paramètre SQL_NULL
est également défini, sauf si sqldata
est passé comme null
.
Lorsque vous écrivez une expression ou que vous spécifiez, par exemple, des conditions de comparaison, vous devez essayer d’utiliser des Types de données compatibles.Si vous devez utiliser des données mixtes de différents types, il est conseillé d’effectuer d’abord les conversions de type, puis d’effectuer les opérations.
Lorsque l’on envisage des conversions de type dans Firebird, il faut prêter une grande attention au dialecte dans lequel se trouve la base de données.
Lorsqu’une conversion explicite d’un type à un autre est nécessaire, la fonction CAST
est utilisée.
CAST (<expression> | NULL AS <data_type>) <data_type> ::= <datatype> | [TYPE OF] domain | TYPE OF COLUMN relname.colname <datatype> ::= <scalar_datatype> | <blob_datatype> | <array_datatype>
scalar_datatype ::= Voir. Syntaxe des types de données scalaires
blob_datatype ::= Voir. Syntaxe des types de données BLOB
array_datatype ::= Voir. Syntaxe des tableaux
Lors de la conversion vers un domaine, les restrictions déclarées pour celui-ci, telles que NOT NULL
ou celles décrites dans CHECK
, sont prises en compte et si <expression>
échoue, la conversion échouera.Si en plus TYPE OF
est spécifié (conversion en type de base), la conversion ignore toute restriction de domaine.Si TYPE OF
est utilisé avec le type [VAR]CHAR
, le jeu de caractères et le tri sont préservés.
Lors de la conversion vers un type de colonne, il est permis d’utiliser une spécification de colonne de table ou de vue.Seul le type de colonne lui-même est utilisé ; dans le cas des types de chaînes de caractères, cela inclut également le jeu de caractères, mais pas le tri.Les contraintes et les valeurs par défaut de la colonne d’origine ne s’appliquent pas.
CREATE TABLE TTT (
S VARCHAR (40)
CHARACTER SET UTF8 COLLATE UNICODE_CI_AI);
COMMIT;
/* J'ai beaucoup d'amis (suédois)*/
SELECT
CAST ('Jag har manga vanner' AS TYPE OF COLUMN TTT.S)
FROM RDB$DATABASE;
CAST
Type d’origine | Cast |
---|---|
Type numérique |
Type numérique, |
|
|
|
|
|
|
|
|
Pour convertir des types de données de type chaîne en type BOOLEAN, l’argument chaîne doit être l’un des littéraux prédéfinis du type logique ('true'
ou 'false'
).
Important
|
Lors de la conversion des types, il faut tenir compte de la possibilité de perte partielle de données, par exemple lors de la conversion du type de données |
Pour convertir des types de données de type chaîne en DATE
, TIME
ou TIMESTAMP
, l’argument chaîne doit être soit un des littéraux de date et d’heure prédéfinis, soit une représentation de la date dans l’un des formats autorisés.
<date_literal> ::= [YYYY<p>]MM<p>DD | MM<p>DD[<p>YYYY] | DD<p>MM[<p>YYYY] | MM<p>DD[<p>YY] | DD<p>MM[<p>YY] <time_literal> := HH[:mm[:SS[.NNNN]]] <datetime_literal> ::= <date_literal> <time_literal> <time zone> ::= <time zone region> | [+/-] <hour displacement> [: <minute displacement>] <p> ::= whitespace | . | , | - | / position: absolute; float: left;
Argument | Description |
---|---|
datetime_literal |
Les littéraux date-heure. |
date_literal |
Date littérale. |
time_literal |
Le temps littéral. |
YYYY |
Une année à quatre chiffres. |
YY |
Les deux derniers chiffres de l’année (00-99). |
MM |
Mois.Peut contenir 1 ou 2 chiffres (1-12 ou 01-12). Le mois peut également être une abréviation de trois lettres ou le nom complet du mois en anglais, sans tenir compte de la casse. |
DD |
Jour.Peut contenir 1 ou 2 chiffres (1-31 ou 01-31). |
HH |
Heure.Peut contenir 1 ou 2 chiffres (0-23 ou 00-23). |
mm |
Minute.Peut contenir 1 ou 2 chiffres (0-59 ou 00-59). |
SS |
Secondes.Peut contenir 1 ou 2 chiffres (0-59 ou 00-59). |
NNNN |
Dix millièmes de seconde.Peut contenir de 1 à 4 chiffres (0-9999). |
p |
Séparateur, n’importe lequel des caractères autorisés, les espaces avant et arrière sont ignorés. |
time zone region |
Un des fuseaux horaires associés à la région |
hour displacement |
Décalage horaire de l’horloge par rapport à GMT |
minute displacement |
Décalage horaire pour les minutes par rapport à GMT |
Les littéraux | Valeur | Type de données pour le dialecte 1 | Type de données pour le dialecte 3 |
---|---|---|---|
|
Date et heure actuelles |
TIMESTAMP |
TIMESTAMP |
|
Date actuelle |
TIMESTAMP (avec un temps nul) |
DATE (date uniquement) |
|
Date de demain |
TIMESTAMP (avec un temps nul) |
DATE (date uniquement) |
|
Date d’hier |
TIMESTAMP (avec un temps nul) |
DATE (date uniquement) |
Règles :
Au format Année-Mois-Jour, l’année doit obligatoirement comporter 4 chiffres ;
Pour les dates au format fin d’année, si un point “.” est utilisé comme séparateur de date, la date est interprétée comme Jour-Mois-Année, pour les autres séparateurs, elle est interprétée comme Mois-Jour-Année ;
Si aucune année n’est spécifiée, l’année en cours est prise comme année ;
Si seulement deux chiffres de l’année sont spécifiés, Firebird utilise l’algorithme de la fenêtre glissante pour obtenir le siècle. La tâche consiste à interpréter la valeur de l’année à deux caractères comme étant la plus proche de l’année en cours dans l’intervalle des 50 années précédentes et suivantes ;
Si aucun élément de temps n’est spécifié, il est supposé être égal à 0.
Lors de l’utilisation de CAST() pour convertir des littéraux de chaîne en type date/heure, la valeur est toujours calculée au moment de l’exécution.
Lors de la conversion de chaînes de caractères avec des valeurs de date et d’heure prédéfinies en type TIMESTAMP, la précision est de 3 décimales (millisecondes).
Tip
|
Nous recommandons vivement de n’utiliser que des formulaires comportant l’année complète à 4 chiffres dans les littéraux de date afin d’éviter toute confusion. |
SELECT
CAST('04.12.2014' AS DATE) AS d1, -- DD.MM.YYYY
CAST('12-04-2014' AS DATE) AS d2, -- MM-DD-YYYY
CAST('12/04/2014' AS DATE) AS d3, -- MM/DD/YYYY
CAST('04.12.14' AS DATE) AS d4, -- DD.MM.YY
-- DD.MM année en cours
CAST('04.12' AS DATE) AS d5,
-- MM/DD année en cours
CAST('12/4' AS DATE) AS d6,
CAST('2014/12/04' AS DATE) AS d7, -- YYYY/MM/DD
CAST('2014.12.04' AS DATE) AS d8, -- YYYY.MM.DD
CAST('2014-12-04' AS DATE) AS d9, -- YYYY-MM-DD
CAST('11:37' AS TIME) AS t1, -- HH:mm
CAST('11:37:12' AS TIME) AS t2, -- HH:mm:ss
CAST('11:31:12.1234' AS TIME) AS t3, -- HH:mm:ss.nnnn
-- HH:mm:ss.nnnn +hh
CAST('11:31:12.1234 +03' AS TIME WITH TIME ZONE) AS t4,
-- HH:mm:ss.nnnn +hh:mm
CAST('11:31:12.1234 +03:30' AS TIME WITH TIME ZONE) AS t5,
-- HH:mm:ss.nnnn tz
CAST('11:31:12.1234 Europe/Moscow' AS TIME WITH TIME ZONE) AS t5,
-- HH:mm tz
CAST('11:31 Europe/Moscow' AS TIME WITH TIME ZONE) AS t6,
-- DD.MM.YYYY HH:mm
CAST('04.12.2014 11:37' AS TIMESTAMP) AS dt1,
-- MM/DD/YYYY HH:mm:ss
CAST('12/04/2014 11:37:12' AS TIMESTAMP) AS dt2,
-- DD.MM.YYYY HH:mm:ss.nnnn
CAST('04.12.2014 11:31:12.1234' AS TIMESTAMP) AS dt3,
-- YYYY-MM-DD HH:mm:ss.nnnn +hh:mm
CAST('2014-12-04 11:31:12.1234 +03:00' AS TIMESTAMP WITH TIME ZONE) AS dt4,
-- DD.MM.YYYY HH:mm:ss.nnnn tz
CAST('04.12.2014 11:31:12.1234 Europe/Moscow' AS TIMESTAMP WITH TIME ZONE) AS dt5,
CAST('now' AS DATE) AS d_now,
CAST('now' AS TIMESTAMP) AS ts_now,
CAST('now' AS TIMESTAMP WITH TIME ZONE) AS ts_now_tz,
CAST('today' AS DATE) AS d_today,
CAST('today' AS TIMESTAMP) AS ts_today,
CAST('today' AS TIMESTAMP WITH TIME ZONE) AS ts_today_tz,
CAST('tomorrow' AS DATE) AS d_tomorrow,
CAST('tomorrow' AS TIMESTAMP) AS ts_tomorrow,
CAST('tomorrow' AS TIMESTAMP WITH TIME ZONE) AS ts_tomorrow_tz,
CAST('yesterday' AS DATE) AS d_yesterday,
CAST('yesterday' AS TIMESTAMP) AS ts_yesterday,
CAST('yesterday' AS TIMESTAMP WITH TIME ZONE) AS ts_yesterday_tz
FROM rdb$database
Note
|
Comme |
CAST('NOW' AS TIMESTAMP)
pour mesurer la durée d’exécution du codeEXECUTE BLOCK
RETURNS (ms BIGINT)
AS
DECLARE VARIABLE t1 TIME;
DECLARE VARIABLE n BIGINT;
BEGIN
t1 = CAST('now' AS TIMESTAMP);
/* Long fonctionnement */
SELECT COUNT(*) FROM rdb$types, rdb$types, rdb$types INTO n;
/*======*/
ms = DATEDIFF(MILLISECOND FROM t1 TO CAST('now' AS TIMESTAMP));
SUSPEND;
END
Dans le dialecte 3, aucune conversion implicite de données n’est possible, ici la fonction CAST
doit être spécifiée pour traduire explicitement un type vers un autre.Toutefois, cela ne s’applique pas à l’opération de concaténation, dans laquelle tous les autres Types de données seront implicitement convertis en un type de caractère.
En utilisant le dialecte 1, de nombreuses expressions effectuent une conversion implicite d’un type vers un autre sans utiliser la fonction CAST
.Par exemple, dans une expression de sélection en dialecte 1, vous pouvez écrire :
WHERE DOC_DATE < '31.08.2014'
et la conversion de la chaîne en date se fera implicitement.
Dans le dialecte 1, il est possible de mélanger des données entières et des chaînes numériques, les chaînes sont implicitement converties en entiers si cela est possible, par ex :
2 + '1'
s’exécutera correctement.
Dans le dialecte 3, une telle expression provoquera une erreur, elle nécessitera une entrée de la forme suivante :
2 + CAST('1' AS SMALLINT)
Lors de la concaténation de plusieurs éléments de types différents, toutes les données qui ne sont pas des chaînes seront implicitement converties en chaînes, si possible.
SELECT 30||' days hath September, April, June and November' CONCAT$
FROM RDB$DATABASE
CONCAT$ ------------------------------------------------ 30 days hath September, April, June and November