FirebirdSQL logo

Ce chapitre couvre les éléments qui sont communs à toutes les implémentations du langage SQL — les expressions qui sont utilisées pour récupérer et opérer sur les déclarations de données, et les prédicats qui vérifient la vérité de ces déclarations.

Expressions

Les expressions SQL représentent des méthodes formelles de calcul, de transformation et de comparaison de valeurs. Les expressions SQL peuvent inclure des colonnes de table, des variables, des constantes, des littéraux, divers opérateurs et prédicats, ainsi que d’autres expressions. Une liste complète des tokens autorisés dans les expressions est décrite ci-dessous.

Description des éléments linguistiques

Nom de la colonne: : Identifiants de colonne des tables spécifiées utilisées dans des calculs ou des comparaisons, ou comme condition de recherche. La colonne de type tableau ne peut pas être un élément d’une expression, sauf s’il est est vérifié pour IS [NOT] NULL.

Éléments du tableau : : Une expression peut contenir une référence à un élément de tableau, c’est-à-dire <nom_du_tableau>[s], où s — l’indice de l’élément dans le tableau.

Opérateurs arithmétiques: : Symboles +, -, *, / utilisés pour calculer les valeurs.

Opérateur de concaténation : : L’opérateur || ("deux lignes verticales") est utilisé pour joindre des chaînes de caractères.

Opérateurs logiques : : Les mots réservés NOT, AND et OR sont utilisés lorsqu’en combinant des termes de recherche simples pour créer des déclarations complexes.

Opérateurs de comparaison

Symboles =, <>, !=, ~=, ^=, <, <=, >, >=, !<, ~<, ^<, !>, ~> et ^>

Prédicats de comparaison

LIKE, STARTING WITH, CONTAINING, SIMILAR TO, BETWEEN, IS [NOT] NULL, IS [NOT] {TRUE | FALSE | UNKNOWN}, et IS [NOT] DISTINCT FROM

Prédicats d’existence : : Prédicats utilisés pour vérifier l’existence de valeurs dans un ensemble. set. Le prédicat IN peut être utilisé avec les deux ensembles de constantes, et avec des sous-requêtes scalaires. Les prédicats EXISTS, SINGULAR, ALL. ANY, SOME ne peuvent être utilisés qu’avec des sous-requêtes.

Constantes et littéraux: : Les nombres, les chaînes de caractères encapsulées par une apostrophe, les chaînes de caractères logiques, etc. valeurs TRUE, FALSE et UNKNOWN, NULL pseudo-définition.

Les littéraux de date et d’heure: : Les expressions similaires aux littéraux de chaîne de caractères inclus dans des apostrophes qui peuvent être interprétées comme une date, des valeurs de temps ou de date. Les littéraux de date peuvent être des chaînes de des caractères et des chiffres, tels que TIMESTAMP '25.12.2016'. 15:30:35', qui peut être converti en date, heure ou la date avec l’heure.

Les mnémoniques de la date et de l’heure: : Chaîne littérale décrivant la valeur de la date et/ou de l’heure souhaitée. l’heure, qui peut être amenée au type de date et/ou d’heure. Pour exemples "NOW", "TODAY".

Variables contextuelles

Construit dans variables de contexte.

Variables locales

Variables locales, paramètres d’entrée ou de sortie des modules PSQL (procédures stockées, déclencheurs, blocs PSQL anonymes).

Paramètres de position

En DSQL, seuls les paramètres positionnels peuvent être utilisés comme paramètres de requête. Les paramètres de position sont les points d’interrogation ( ?) dans une déclaration DSQL. Ces paramètres sont accessibles par leur numéro (la position dans la requête) par rapport au paramètre de positionnement précédent, ils sont donc appelé positionnel. En général, les composants d’accès permettent de travailler avec des paramètres nommés, qui sont eux-mêmes converti en paramètres de position.

Sous-requêtes

L’instruction SELECT entre parenthèses, qui renvoie une valeur unique (scalaire) ou un ensemble de valeurs (lorsque utilisés dans les prédicats d’existence).

Identificateurs de fonction

Identificateurs des fonctions intégrées ou externes dans les fonctions expressions.

Conversions de type

Expression de conversion explicite d’un type de données à un autre en utilisant CAST comme CAST(<value> AS <datatype>).

Expressions conditionnelles

Expression CASE et fonctions intégrées COALESCE, NULLIF.

Entre parenthèses

Une paire de parenthèses ( …​ ) est utilisée pour regrouper des expressions. Les opérations à l’intérieur des parenthèses sont effectuées avant les opérations à l’extérieur des parenthèses. Lorsqu’en utilisant des parenthèses imbriquées, les valeurs des expressions les plus internes sont calculées en premier, puis le calcul est déplacé vers le haut. d’abord les expressions internes, puis le calcul est déplacé vers le haut par le biais de niveaux de nidification.

Propriété COLLATE: : La déclaration s’applique aux types CHAR et VARCHAR pour définir les paramètres de tri utilisés dans la comparaison.

NEXT VALUE FOR sequence

Le constructeur NEXT VALUE FOR permet d’obtenir la valeur suivante de la séquence, la même chose est faite par la fonction intégrée GEN_ID().

Expression AT

Expression permettant de modifier le fuseau horaire de la date et de l’heure.

Littéraux (constantes)

Littéraux ou constante est une valeur insérée directement dans l’instruction SQL qui n’est pas dérivée d’une expression, d’un paramètre, d’une référence de colonne ou d’une variable.

Littérales de chaînes de caractères

Une chaîne de caractères est une séquence de caractères placée entre deux apostrophes (“guillemets simples”). La longueur maximale d’une constante de chaîne est de 65535 octets ; le nombre maximal de caractères sera déterminé par le nombre d’octets utilisés pour coder chaque caractère.

Syntaxe:
<character string literal> ::=
  [ <introducer> <character set specification> ]
    <quote> [ <character representation>... ] <quote>
    [ { <separator> <quote> [ <character representation>... ] <quote> }... ]

<separator> ::=
  { <comment> | <white space> }

<introducer> ::= underscore (U+005F)

<quote> ::= apostrophe (U+0027)

<char> ::= character representation;
l'apostrophe est échappée en la doublant
Example 1. Chaîne littérale simple
'Hello world'

Si une apostrophe littérale est requise dans une constante de chaîne, elle peut être "protégée" par une autre apostrophe qui la précède.

Example 2. Chaîne littérale contenant une apostrophe
'Mother O''Reilly''s home-made hooch'

Une autre façon d’écrire cette chaîne littérale est d’utiliser des guillemets alternatifs :

q'{Mother O'Reilly's home-made hooch}'

Un littéral de chaîne peut être "terminé" par un espace ou un commentaire si nécessaire. Cela peut être utilisé pour diviser un long littéral en plusieurs lignes ou pour fournir des commentaires en ligne.

Example 3. Chaînes littérales interrompues par un espace et un commentaire
-- Des espaces entre les caractères littéraux
select 'ab'
       'cd'
from RDB$DATABASE;
-- sortie: 'abcd'

-- Des espaces entre les commentaires littéraux
select 'ab' /* comment */ 'cd'
from RDB$DATABASE;
-- sortie: 'abcd'
Note
  • Les guillemets doubles devraient ne pas (autorisés par 1 dialecte) être utilisés pour le quota de chaînes. Dans SQL, ils sont fournis à d’autres fins.

  • Si une apostrophe littérale est requise dans une constante de chaîne, elle peut être "`screened'" par une autre apostrophe précédente. Par exemple, "Mother O''Reilly’s home-made hooch". Ou utilisez des guillemets alternés pour les littéraux : q'{Mother O''Reilly's home-made hooch}'.

  • Il faut faire attention à la longueur de la chaîne si la valeur doit être écrite dans une colonne de type VARCHAR. La longueur maximale de la chaîne pour le type VARCHAR est de 32765 octets (32767 pour le type CHAR). Si la valeur doit être écrite dans une colonne de type BLOB, la longueur maximale de la chaîne littérale est de 65535 octets.

On suppose que le jeu de caractères de la constante chaîne est le même que celui de la colonne dans laquelle elle est stockée.

Constantes de chaîne en notation hexadécimale

Depuis Firebird 2.5, les constantes de type chaîne peuvent être écrites en notation hexadécimale, ce que l’on appelle des “chaînes binaires”. Chaque paire de chiffres hexadécimaux définit un octet dans la chaîne. Les chaînes de caractères entrées de cette façon auront l’encodage OCTETS par défaut, Mais introducer syntax peut être utilisé pour forcer la chaîne à être interprétée dans un jeu de caractères différent.

Syntaxe:
{x|X}'<hexstring>'

<hexstring> ::= an even number of <hexdigit>

<hexdigit> ::= 0..9 | A..F | a..f
Example 1. Exemples:
SELECT x'4E657276656E' FROM rdb$database
-- returns 4E657276656E, a 6-byte 'binary' string

SELECT _ascii x'4E657276656E' FROM rdb$database
-- returns 'Nerven' (same string, now interpreted as ASCII text)

SELECT _iso8859_1 x'53E46765' FROM rdb$database
-- returns 'Säge' (4 chars, 4 bytes)

SELECT _utf8 x'53C3A46765' FROM rdb$database
-- returns 'Säge' (4 chars, 5 bytes)
Note

La façon dont les chaînes binaires sont affichées dépend de l’interface client. Par exemple, l’utilitaire isql utilise les lettres majuscules A-F, tandis que FlameRobin utilise les lettres minuscules. D’autres peuvent utiliser d’autres règles de conversion, comme l’affichage d’espaces entre les paires d’octets : "4E 65 72 76 65 6E".

La notation hexadécimale permet d’insérer n’importe quel octet (y compris 00) à n’importe quelle position dans une chaîne.

Un littéral peut contenir des espaces pour séparer les caractères hexadécimaux. Un littéral de chaîne peut être "terminé" par un espace ou un commentaire si nécessaire. Cela peut être utilisé pour rendre une chaîne hexadécimale plus lisible en regroupant les caractères, ou pour diviser un long littéral en plusieurs lignes, ou encore pour fournir des commentaires en ligne.

Example 2. Littéral binaire interrompu par un espace
-- Groupe par octet (espace à l'intérieur du littéral)
select _win1252 x'42 49 4e 41 52 59'
from RDB$DATABASE;
-- sortie: BINARY

-- Espacement entre les caractères littéraux
select _win1252 x'42494e'
                 '415259'
from RDB$DATABASE;
-- sortie: BINARY
Alternatives pour les apostrophes dans les littéraux de chaînes de caractères

Au lieu d’une double apostrophe (échappée), vous pouvez utiliser un autre caractère ou une paire de caractères.

Le mot-clé q ou Q précédant une chaîne de caractères entre guillemets indique à l’analyseur syntaxique que certaines paires gauche et droite de mêmes caractères sont des délimiteurs pour le littéral de chaîne intégré.

Syntaxe:
<alternate string literal> ::=
  { q | Q } <quote> <alternate start char>
  [ { <char> }... ]
  <alternate end char> <quote>
Note
Règles d’utilisation

Lorsque <caractère alternatif de début> est l’un des caractères '(', '{', '[' ou '<', alors <caractère alternatif de fin> doit être utilisé en conjonction avec un `partenaire' approprié, tel que ')', '}', ']' ou '>'. Dans les autres cas, <caractère de fin alternatif> est le même que <caractère de début alternatif>.

À l’intérieur d’une chaîne de caractères, c’est-à-dire des éléments <char>, il est possible d’utiliser des guillemets simples (non masqués). Chaque guillemet fera partie de la chaîne de caractères résultante.

Example 1. Utilisation d’apostrophes alternatives dans les chaînes de caractères
-- result: abc{def}ghi
SELECT Q'{abc{def}ghi}' FROM rdb$database;

-- result: That's a string
SELECT Q'!That's a string!' FROM rdb$database;
Example 2. Assemblage dynamique de requêtes à l’aide de chaînes de caractères.
EXECUTE BLOCK
RETURNS (
  RDB$TRIGGER_NAME CHAR(64)
)
AS
  DECLARE VARIABLE S VARCHAR(8191);
BEGIN
  S = 'SELECT RDB$TRIGGER_NAME FROM RDB$TRIGGERS WHERE RDB$RELATION_NAME IN ';
  S = S || Q'! ('SALES_ORDER', 'SALES_ORDER_LINE')!';
  FOR
    EXECUTE STATEMENT :S
    INTO :RDB$TRIGGER_NAME
  DO
    SUSPEND;
END
Jeu de caractères pour les chaînes littérales

Si nécessaire, un littéral de chaîne de caractères peut être précédé d’un nom de jeu de caractères qui commence par le préfixe de soulignement “_”. C’est ce qu’on appelle la syntaxe de l’introducteur. Son but est d’indiquer à Firebird comment interpréter et stocker une chaîne entrante.

Example 1. Syntaxe d’introduction pour les littéraux de chaînes de caractères
-- notez le préfixe '_'
INSERT INTO People
VALUES (_ISO8859_1 'Hans-Jörg Schäfer');

Constantes numériques

Une constante numérique est un nombre valide dans l’une des notations prises en charge :

  • En SQL, pour les nombres en notation décimale standard, le point décimal est toujours représenté par un caractère de point et les milliers ne sont pas séparés. L’inclusion de virgules, d’espaces, etc. entraînera des erreurs.

  • Notation exponentielle, par exemple le nombre 0.0000234 peut être écrit comme 2.34e-5.

  • La notation hexadécimale (voir ci-dessous) des nombres est supportée à partir de Firebird 2.5.

Le tableau suivant présente les formats des littéraux numériques et leurs types. Où <d> est un chiffre décimal, <h> est un chiffre hexadécimal.

Table 1. Format des constantes numériques
Format Type

<d>[<d> …​]

INTEGER, BIGINT, INT128 ou DECFLOAT(34) (dépend du fait que la valeur corresponde ou non au type de). DECFLOAT(34) est utilisé pour les valeurs qui ne rentrent pas dans le type INT128.

0{x|X} <h>[<h> …​]

INTEGER pour les chiffres hexadécimaux de 1 à 8, BIGINT pour les chiffres de 9 à 16, INT128 pour les chiffres de 17 à 32 (disponible avec Firebird 4.0.1).

<d>[<d> …​].[<d> …​]

NUMERIC(18, n), NUMERIC(38, n) ou DECFLOAT(34)n dépend du nombre de chiffres après la virgule et la précision du nombre total de chiffres.

Pour des raisons de compatibilité ascendante, certaines valeurs à 19 chiffres sont mappées en NUMERIC(18, n). DECFLOAT(34) est utilisé lorsque la valeur non scalée ne tient pas dans INT128.

<d>[<d> …​][. [<d> …​]] E <d>[<d> …​]

DOUBLE PRECISION ou DECFLOAT(34), où DECFLOAT n’est utilisé que si le nombre de chiffres est égal ou supérieur à 20, ou si la valeur absolue de l’exposant est égale ou supérieure à 309.

Notation hexadécimale des nombres

Les constantes entières peuvent être spécifiées au format hexadécimal. A partir de Firebird 4.0.1, les nombres composés de 17 à 32 chiffres hexadécimaux seront interprétés comme INT128.

Syntaxe:
{x|X}<hexdigits>

<hexdigits> ::= 1-32 of <hexdigit>

<hexdigit> ::= 0..9 | A..F | a..f
Table 1. Constantes de types entiers au format hexadécimal
Nombre de chiffres hexadécimaux Type de données

1-8

INTEGER

9-16

BIGINT

17-32

INT128

Example 1. Constantes hexadécimales
SELECT 0x6FAA0D3 FROM rdb$database -- returns 117088467
SELECT 0x4F9 FROM rdb$database -- returns 1273
SELECT 0x6E44F9A8 FROM rdb$database -- returns 1850014120
SELECT 0x9E44F9A8 FROM rdb$database -- returns -1639646808 (INTEGER)
SELECT 0x09E44F9A8 FROM rdb$database -- returns 2655320488 (BIGINT)
SELECT 0x28ED678A4C987 FROM rdb$database -- returns 720001751632263
SELECT 0xFFFFFFFFFFFFFFFF FROM rdb$database -- returns -1
Plage de valeurs hexadécimales
  • Nombres hexadécimaux dans la plage 0 . 7FFF FFFF sont des nombres positifs INTEGER avec les valeurs 0 . 2147483647. Pour interpréter une constante comme un nombre BIGINT, vous devez ajouter le nombre de zéros à gauche. Cela changera le type mais pas la valeur.

  • Numéros dans la plage 8000 0000 . FFFF FFFF nécessitent une attention particulière :

    • Lorsqu’ils sont écrits avec huit nombres hexadécimaux tels que 0x9E44F9A8, ils sont interprétés comme des entiers de 32 bits. Le bit le plus à gauche (le chiffre|la signature) étant activé, ces nombres se situent dans la plage négative -2147483648 . -1.

    • Les nombres précédés d’un ou plusieurs zéros, tels que 0x09E44F9A8, seront interprétés comme des BIGINT 64 bits dans la plage de valeurs 0000 0000 8000 0000 . 0000 0000 0000 FFFF FFFF. Dans ce cas, le bit de signature n’est pas activé, ils sont donc affichés dans la plage positive 2147483648 .. 4294967295 nombres décimaux.

    Ainsi, ce n’est que dans cet intervalle que les nombres précédés d’un zéro totalement insignifiant ont des valeurs radicalement différentes. Vous devez en être conscient.

  • Nombres hexadécimaux dans la plage 1 0000 0000 . 7FFF FFFF FFFF FFFF sont des nombres positifs `BIGINT'.

  • Nombres hexadécimaux dans la plage 8000 0000 0000 0000 0000 …​ FFFF FFFF FFFF FFFF sont des nombres `BIGINT' négatifs.

  • Les nombres de type SMALLINT ne peuvent pas être écrits en hexadécimal, à proprement parler, puisque même 0x1 est évalué comme INTEGER. Cependant, si vous écrivez un entier positif dans la plage de 16 bits allant de 0x0000 (zéro décimal) à 0x7FFF (32767 décimal), il sera converti en SMALLINT de manière transparente.

    Vous pouvez écrire un nombre SMALLINT négatif en hexadécimal en utilisant un nombre hexadécimal de 4 octets allant de 0xFFFF8000 (décimal -32768) à 0xFFFFFFFFFF (décimal -1).

Les littéraux logiques

Un littéral logique peut prendre l’une des valeurs suivantes : TRUE, FALSE ou UNKNOWN.

Déclarations SQL

Les instructions SQL comprennent des opérateurs pour comparer, calculer, évaluer et concaténer des valeurs.

Préséance des opérateurs

La priorité détermine l’ordre dans lequel les opérateurs et les valeurs qu’ils produisent sont évalués dans une expression.

Tous les opérateurs sont divisés en 4 types. Chaque type d’opérateur a une priorité différente. Plus la priorité d’un type d’opérateur est élevée, plus il sera évalué tôt. Au sein d’un même type, les opérateurs ont leur propre priorité, qui détermine également l’ordre dans lequel ils sont évalués dans une expression. Les opérateurs ayant la même priorité sont calculés de gauche à droite. Les opérations peuvent être regroupées entre parenthèses pour modifier l’ordre de calcul.

Table 1. Types d’opérateurs prioritaires
Type d’opérateur Priorité Explication

Concaténation

1

Les lignes sont concaténées avant toute autre opération.

Arithmétique

2

Les opérations arithmétiques sont effectuées après la concaténation. mais avant d’exécuter la comparaison et les opérations logiques.

Comparaison

3

Les opérations de comparaison sont calculées après la concaténation de chaînes et les opérations arithmétiques, mais avant les opérations logiques.

Logic

4

Les opérateurs logiques sont exécutés après tous les autres types d’opérateurs. opérateurs.

Opérateur de concaténation

L’opérateur de concaténation || joint deux chaînes de caractères et crée une seule chaîne. Les piles de caractères peuvent être des constantes ou des valeurs dérivées de colonnes ou d’autres expressions.

Example 1. Opérateur de concaténation
SELECT LAST_NAME || ', ' || FIRST_NAME AS FULL_NAME
FROM EMPLOYEE

Opérateurs arithmétiques

Table 1. Priorité des opérateurs arithmétiques
Opérateur Affectation Priorité

+signed_number

Unaire plus

1

-signed_number

Moins unaire

1

*

Multiplication

2

/

Division

2

+

Addition

3

-

Soustraction

3

Example 1. Opérateurs arithmétiques
UPDATE T
SET A = 4 + 1/(B-C)*D

Opérateurs de comparaison

Table 1. Opérateurs de comparaison
Opérateur Affectation Priorité

IS

Vérifie si l’expression du côté gauche est un pseudo NULL ou correspond à la valeur logique dans le champ côté droit.

1

=

Égale, identique

2

<>, !=, ~=, ^=

Non égal

2

>

Plus grand que

2

<

Plus petit que

2

>=

Suppérieur ou égal

2

<=

Inférieur ou égal à

2

!>, ~>, ^>

Pas plus

2

!<, ~<, ^<

Pas moins

2

Le même groupe comprend les prédicats de comparaison IS DISTINCT FROM, BETWEEN, IN, LIKE, CONTAINING, SIMILAR TO et autres.

Example 1. Utilisation de l’opérateur de comparaison
IF (SALARY > 1400) THEN
...

Opérateurs logiques

Table 1. Priorité des opérateurs logiques
Opérateur Affectation Priorité

NOT

Négation d’une condition de recherche.

1

AND

Combine deux prédicats ou plus, chacun d’entre eux doit être vrai pour que l’ensemble du prédicat soit vrai.

2

OR

Combine deux ou plusieurs prédicats, dont au moins un doit être vrai. Il faut qu’au moins un prédicat soit vrai pour que l’ensemble du prédicat soit également vrai.

3

Example 1. Utilisation des opérateurs logiques
IF (A > B OR (A > C AND A > D) AND NOT (C = D)) THEN
...

AT

Disponible en

DSQL, PSQL.

Syntaxe
<expr> AT {TIME ZONE <time zone string> | LOCAL}

<time zone string> ::=
    '<time zone>'

<time zone> ::=
    <time zone region> |
    [+/-] <hour displacement> [: <minute displacement>]

Convertit l’heure ou l’horodateur dans le fuseau horaire spécifié. Si le mot-clé LOCAL est utilisé, la conversion se fait vers le fuseau horaire de la session.

Example 1. Utilisation de la fonction AT
select time '12:00 GMT' at time zone '-03'
  from rdb$database;

select current_timestamp at time zone 'America/Sao_Paulo'
  from rdb$database;

select timestamp '2018-01-01 12:00 GMT' at local
  from rdb$database;

NEXT VALUE FOR

Disponible en DSQL, PSQL.

Syntaxe
NEXT VALUE FOR sequence-name

Renvoie la valeur suivante dans la séquence (SEQUENCE). SEQUENCE est un terme générateur compatible avec SQL dans InterBase et Firebird. L’opérateur NEXT VALUE FOR est totalement équivalent à la fonction GEN_ID (sequence-name, 1) et constitue la syntaxe recommandée.

Note

La phrase NEXT VALUE FOR ne prend pas en charge une valeur différente de celle spécifiée lorsque la séquence a été créée dans la phrase INCREMENT [BY]. Si une valeur différente est requise, utilisez l’ancienne fonction GEN_ID.

Example 1. Utilisation de NEXT VALUE FOR
NEW.CUST_ID = NEXT VALUE FOR CUSTSEQ;
Voir aussi :

SEQUENCE (GENERATOR), GEN_ID.

Expressions conditionnelles

Une expression conditionnelle est une expression qui renvoie différentes valeurs en fonction de la véracité d’une ou plusieurs conditions. Cette section ne décrit qu’une seule expression conditionnelle CASE. Les autres expressions conditionnelles sont des fonctions intégrées dérivées et sont décrites dans Fonctions conditionnelles.

CASE

Disponible en

DSQL, ESQL.

L’opérateur CASE ne renvoie qu’une seule valeur parmi plusieurs possibles. Il existe deux variantes de syntaxe :

  • Un simple CASE, comparable à Pascal case ou C switch ;

  • Une CASE interrogeable qui fonctionne comme une série d’opérateurs if …​ sinon si …​ sinon si .

Simple CASE
Syntaxe
CASE <test-expr>
  WHEN <expr> THEN <result>
  [WHEN <expr> THEN <result> ...]
  [ELSE <defaultresult>]
END

Avec cette variante, la test-expr est comparée à la première expr, puis le deuxième expr, et ainsi de suite, jusqu’à ce qu’une correspondance soit trouvée, auquel cas le résultat correspondant est renvoyé. Si aucune correspondance n’est trouvée, le résultat par défaut de la branche ELSE est retourné. S’il n’y a pas de correspondance et que la branche ELSE est manquante, il retourne NULL.

Une correspondance est équivalente à l’opérateur “=”, c’est-à-dire que Si test-expr a la valeur NULL, alors il ne correspond à aucune des expr, même celles qui ont la valeur NULL.

Les résultats ne doivent pas nécessairement être des valeurs littérales, ils peuvent aussi être des noms de champs, des variables, des expressions complexes ou des NULL.

Example 1. En utilisant un simple CASE
SELECT
  NAME,
  AGE,
  CASE UPPER(SEX)
    WHEN 'M' THEN 'Male'
    WHEN 'F' THEN 'Female'
    ELSE 'Unknown'
  END AS SEXNAME,
  RELIGION
FROM PEOPLE

Une forme abrégée de l’opérateur CASE simple est utilisée dans la fonction DECODE.

Recherche CASE
Syntaxe
CASE
  WHEN <bool_expr> THEN <result>
  [WHEN <bool_expr> THEN <result> …]
  [ELSE <defaultresult>]
END

Ici <bool_expr> est une expression qui donne un triple résultat logique : TRUE, FALSE ou NULL. La première expression qui retourne TRUE définit le résultat. Si aucune expression ne retourne TRUE, le résultat par défaut de la branche ELSE est pris comme résultat. Si aucune expression ne retourne TRUE et qu’il n’y a pas de branche ELSE, le résultat est NULL.

Comme avec l’instruction simple CASE, les résultats ne doivent pas nécessairement être des valeurs littérales : ils peuvent être des champs ou des noms de variables, des expressions complexes ou NULL.

Example 1. Utilisation d’un moteur de recherche CASE
CANVOTE = CASE
  WHEN AGE >= 18 THEN 'Yes'
  WHEN AGE < 18 THEN 'No'
  ELSE 'Unsure'
END;

En termes de NULL

NULL n’est pas une valeur — c’est un état indiquant que la valeur de l’élément est inconnue ou n’existe pas. Ce n’est pas zéro, ni void, ni `chaîne vide', et il ne se comporte pas comme l’une de ces valeurs.

Lorsque vous utilisez NULL dans des expressions numériques, de chaîne de caractères ou de date/heure, vous obtenez toujours NULL. Lorsque vous utilisez NULL dans des expressions logiques (booléennes), le résultat dépendra du type d’opération et des autres valeurs impliquées. Si vous comparez une valeur à NULL, le résultat sera indéfini (UNKNOWN).

Important

Le résultat logique indéfini UNKNOWN est également représenté par la pseudo-valeur NULL.

Les expressions qui reviennent NULL

Les expressions de cette liste retourneront toujours NULL:

1 + 2 + 3 + NULL
'Home ' || 'sweet ' || NULL
MyField = NULL
MyField <> NULL
NULL = NULL
not (NULL)

Si vous avez du mal à comprendre pourquoi, rappelez-vous que NULL signifie inconnu.

NULL dans les expressions logiques

Nous avons déjà considéré que not (NULL) résulte en NULL. Pour les opérateurs AND et OR, l’interaction est un peu plus compliquée :

NULL or false → NULL
NULL or true → true
NULL or NULL → NULL
NULL and false → false
NULL and true → NULL
NULL and NULL → NULL
Example 1. NULL et les expressions logiques
(1 = NULL) or (1 <> 1)    -- returns NULL
(1 = NULL) or FALSE       -- returns NULL
(1 = NULL) or (1 = 1)     -- returns TRUE
(1 = NULL) or TRUE        -- returns TRUE
(1 = NULL) or (1 = NULL)  -- returns NULL
(1 = NULL) or UNKNOWN     -- returns NULL
(1 = NULL) and (1 <> 1)   -- returns FALSE
(1 = NULL) and FALSE      -- returns FALSE
(1 = NULL) and (1 = 1)    -- returns NULL
(1 = NULL) and TRUE       -- returns NULL
(1 = NULL) and (1 = NULL) -- returns NULL
(1 = NULL) and UNKNOWN    -- returns NULL

Sous-requêtes

Une sous-requête est un type particulier d’expression qui est en fait une requête intégrée dans une autre requête. Les sous-requêtes sont écrites comme des requêtes SELECT normales, mais elles doivent être mises entre parenthèses. Les expressions de sous-requêtes sont utilisées de la manière suivante :

  • Pour spécifier une colonne de sortie dans une liste de sélection SELECT ;

  • Pour obtenir des valeurs ou des conditions pour les prédicats de recherche (phrases WHERE, HAVING) ;

  • Pour créer un ensemble de données à partir duquel la requête d’inclusion peut sélectionner comme s’il s’agissait d’une table ou d’une vue ordinaire. Ces sous-requêtes apparaissent dans la phrase FROM (tables dérivées) ou dans une expression de table générique (CTE).

Sous-requêtes liées

Une sous-requête peut être liée (corrélée). Une requête est dite corrélée lorsque la sous-requête et la requête principale sont interdépendantes. Cela signifie que pour chaque enregistrement de la sous-requête à traiter, un enregistrement de la requête principale doit également être récupéré, c’est-à-dire que la sous-requête est entièrement dépendante de la requête principale.

Example 1. Sous-requête liée
SELECT *
FROM Customers C
WHERE EXISTS
      (SELECT *
       FROM Orders O
       WHERE C.cnum = O.cnum
         AND O.adate = DATE '10.03.1990');

Lorsque vous utilisez des sous-requêtes pour récupérer les valeurs des colonnes de sortie dans une liste de sélection SELECT, la sous-requête doit retourner un résultat scalaire.

Sous-requêtes retournant un résultat scalaire

Les Sous-requêtes utilisées dans les prédicats de recherche, à l’exception des prédicats d’existence et de quantité, doivent retourner un résultat scalaire, c’est-à-dire pas plus d’une colonne d’une seule ligne sélectionnée ou une valeur agrégée, sinon une erreur d’exécution (“Multiple rows in a singleton select…​”) se produira.

Note

Bien que Firebird signale une erreur réelle, le message peut être légèrement trompeur. “singleton SELECT” est une requête qui ne doit pas retourner plus d’une chaîne. Cependant, singleton et scalar ne sont pas synonymes : tous les SELECTS à un seul élément ne doivent pas être scalaires ; et un échantillonnage à une seule colonne peut retourner plusieurs lignes pour les prédicats d’existence et de quantité.

Example 1. Sous-requête comme colonne de sortie dans la liste de sélection
SELECT
    e.first_name,
    e.last_name,
    (SELECT
         sh.new_salary
     FROM
         salary_history sh
     WHERE
         sh.emp_no = e.emp_no
     ORDER BY sh.change_date DESC ROWS 1) AS last_salary
FROM
    employee e
Example 2. Sous-requête dans une instruction WHERE pour obtenir la valeur du salaire maximum de l’employé et filtrer par celle-ci.
SELECT
    e.first_name,
    e.last_name,
    e.salary
FROM
    employee e
WHERE
    e.salary = (SELECT
                    MAX(ie.salary)
                FROM
                    employee ie)

Prédicats

Prédicat — est une simple expression affirmant un certain fait, appelons-le P. Si P est résolu comme VRAI, il réussit. S’il prend FALSE ou NULL (UNKNOWN), il échoue. Cependant, il y a un piège ici : supposons que le prédicat P renvoie FALSE. Dans ce cas, NOT (P) retournera VRAI. D’autre part, si P renvoie NULL (inconnu), alors NOT (P) renvoie également NULL.

En SQL, les prédicats sont vérifiés dans la contrainte CHECK, la clause WHERE, la clause CASE, la condition de jointure dans la phrase ON pour les phrases JOIN, et dans la clause HAVING. Dans PSQL, les opérateurs de contrôle du flux d’exécution vérifient les prédicats dans les phrases IF, WHILE et WHEN. Depuis que Firebird 3.0 a introduit le support des types logiques, le prédicat peut apparaître dans n’importe quelle expression valide.

Imbrications

Les conditions vérifiables ne sont pas toujours des prédicats simples. Il peut s’agir d’un groupe de prédicats, dont chacun, lorsqu’il est calculé, contribue au calcul de la vérité globale. Ces conditions complexes sont appelées assertions. Les assertions peuvent être constituées d’un ou plusieurs prédicats liés par les opérateurs logiques AND, OR et NOT. Les parenthèses peuvent être utilisées pour regrouper des prédicats et contrôler l’ordre des calculs.

Chacun des prédicats peut contenir des prédicats imbriqués. Le résultat du calcul de la vérité d’une déclaration est obtenu en calculant tous les prédicats dans la direction de l’interne vers l’externe. Chaque "niveau" est calculé par ordre de priorité jusqu’à obtenir la valeur de vérité de l’énoncé final.

Prédicats de comparaison

Un prédicat de comparaison est constitué de deux expressions jointes par un opérateur de comparaison. Il existe six opérateurs de comparaison traditionnels :

=, >, <, >=, <=, <>

(Voir Opérateurs de comparaison pour une liste complète des opérateurs de comparaison).

Si une partie (gauche ou droite) d’un prédicat de comparaison contient NULL, la valeur du prédicat est indéfinie (UNKNOWN).

Example 1. Prédicats de comparaison

Obtenez des informations sur les ordinateurs dotés d’un processeur d’une fréquence d’au moins 500 MHz et d’un prix inférieur à 800 €.

SELECT *
FROM Pc
WHERE speed >= 500 AND price < 800;

Obtenez des informations sur toutes les imprimantes qui sont des imprimantes à matrice de points et qui coûtent moins de 300 €.

SELECT *
FROM Printer
WHERE type = 'matrix' AND price < 300;

La requête suivante ne retournera aucune entrée car la comparaison est faite avec une pseudo-valeur de NULL, même s’il existe des imprimantes avec un type non spécifié.

SELECT *
FROM Printer
WHERE type = NULL AND price < 300;
Note
Note sur les comparaisons de chaînes de caractères

Lors de la comparaison de l’égalité des types de champs CHAR et VARCHAR, les espaces de fin sont ignorés dans tous les cas.

Autres prédicats de comparaison

Les autres prédicats de comparaison sont constitués de mots-clés.

BETWEEN

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
<value> [NOT] BETWEEN <value_1> AND <value_2>

Le prédicat BETWEEN vérifie si une valeur se situe (ou ne se situe pas en utilisant NOT) dans une plage de valeurs inclusive.

Les opérandes du prédicat BETWEEN sont deux arguments de types compatibles. Contrairement à d’autres bases de données, dans Firebird le prédicat BETWEEN n’est pas symétrique. La plus petite valeur doit être le premier argument, sinon le prédicat BETWEEN sera toujours faux. La recherche est une recherche inclusive. Ainsi, le prédicat BETWEEN peut être réécrit comme suit :

<value> >= <value_1> AND <value> <= <value_2>

Lors de l’utilisation du prédicat BETWEEN dans les termes de recherche des requêtes DML, l’optimiseur Firebird peut utiliser un index sur la colonne recherchée, si disponible.

Example 1. Utilisation d’un prédicat BETWEEN
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN date '01.01.1992' AND CURRENT_DATE

LIKE

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
<match value> [NOT] LIKE <pattern>
  [ESCAPE <escape character>]

<match value> ::=  expression de type caractère
<pattern> ::= modèle de recherche
<escape character> ::= caractère d’échappement

Le prédicat LIKE compare une expression de type caractère avec le motif défini dans la seconde expression. La sensibilité à la casse ou aux signes diacritiques dans la comparaison est déterminée par le paramètre de tri utilisé (COLLATION).

Lorsque vous utilisez l’opérateur LIKE, tous les caractères de la chaîne de caractères du motif sont pris en compte. Cela s’applique également aux espaces avant et arrière. Si une opération de correspondance dans une requête doit renvoyer toutes les chaînes contenant des chaînes LIKE 'abv' (avec un caractère d’espacement à la fin), une chaîne contenant 'abv' (sans caractère d’échappement) ne sera pas renvoyée.

Caractères génériques

Deux symboles génériques peuvent être utilisés dans le modèle de recherche :

  • le caractère pourcentage (%) remplace une séquence de caractères quelconques (le nombre de caractères de la séquence peut être égal ou supérieur à 0) dans la valeur à vérifier ;

  • Un caractère de soulignement (_), qui peut être utilisé à la place de n’importe quel caractère dans la valeur testée.

Si la valeur testée correspond au modèle, y compris les caractères génériques, le prédicat est vrai.

Utiliser un caractère d’échappement dans une phrase ESCAPE

Si la chaîne recherchée contient un caractère générique, un caractère de contrôle doit être spécifié dans la clause ESCAPE. Ce caractère de contrôle doit être utilisé dans le motif avant le caractère générique, indiquant que ce dernier doit être traité comme un caractère normal.

Exemples d’utilisation du prédicat LIKE
Example 1. Recherche de chaînes de caractères qui commencent par une sous-chaîne donnée à l’aide d’un prédicat. LIKE

Recherchez les numéros de département qui commencent par le mot “Software”

SELECT DEPT_NO
FROM DEPT
WHERE DEPT_NAME LIKE 'Software%';

Un index peut être utilisé dans cette requête s’il est construit sur le champ DEPT_NAME.

Note
Optimisation LIKE

En général, le prédicat LIKE n’utilise pas d’index. Cependant, si le prédicat prend la forme LIKE 'string%', il sera converti en un prédicat STARTING WITH qui utilisera un index. Si vous devez effectuer une recherche à partir du début d’une chaîne, il est recommandé d’utiliser le prédicat STARTING WITH au lieu du prédicat LIKE. STARTING WITH.

Example 2. Utilisation du caractère générique “_” dans un prédicat LIKE

Recherchez les employés dont le nom comporte 5 lettres commençant par “Sm” et finissant par “th”. Dans ce cas, le prédicat sera vrai pour les noms “Smith” et “Smyth”.

SELECT
    first_name
FROM
    employee
WHERE first_name LIKE 'Sm_th'
Example 3. Recherche dans une chaîne de caractères à l’aide d’un prédicat LIKE

Recherche de tous les clients dont l’adresse contient la chaîne “Rostov”.

SELECT *
FROM CUSTOMER
WHERE ADDRESS LIKE '%Rostov%'
Tip

Si vous devez effectuer une recherche à l’intérieur d’une chaîne, nous vous recommandons d’utiliser le prédicat CONTAINING au lieu du prédicat LIKE. CONTAINING.

Utilisation du caractère de contrôle dans une phrase ESCAPE avec un prédicat LIKE.

Recherche les tables qui contiennent un caractère de soulignement dans leur nom. Dans ce cas, le caractère de contrôle est “#”.

SELECT
  RDB$RELATION_NAME
FROM RDB$RELATIONS
WHERE RDB$RELATION_NAME LIKE '%#_%' ESCAPE '#'

STARTING WITH

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
<value> [NOT] STARTING WITH <start-value>

Le prédicat STARTING WITH recherche une chaîne qui commence par les caractères de son argument start-value. La sensibilité à la casse et aux accents de STARTING WITH dépend du tri (COLLATION) du premier argument value.

Lorsque vous utilisez le prédicat STARTING WITH dans les termes de recherche des requêtes DML, l’optimiseur de Firebird peut utiliser un index sur la colonne recherchée s’il est défini.

Example 1. Utilisation d’un prédicat STARTING WITH

Recherchez les employés dont le nom de famille commence par "Jo".

SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEE
WHERE LAST_NAME STARTING WITH 'Jo'
Voir aussi :

LIKE.

CONTAINING

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
<value> [NOT] CONTAINING <substring>

L’opérateur CONTAINING recherche une chaîne ou un type de chaîne en trouvant une séquence de caractères qui correspond à son argument. Il peut être utilisé pour des recherches alphanumériques (sous forme de chaîne de caractères) dans des nombres et des dates. Les recherches de type CONTAINING ne sont pas sensibles à la casse. Toutefois, si un tri sensible aux accents est utilisé, la recherche sera sensible aux accents.

Lorsque l’on utilise l’opérateur CONTAINING, tous les caractères d’une chaîne sont pris en compte. Cela s’applique également aux espaces avant et arrière. Si l’opération de comparaison dans une requête doit retourner toutes les chaînes contenant des chaînes CONTAINING 'abv' (avec un caractère d’espacement à la fin), une chaîne contenant 'abv' (sans caractère d’espacement) ne sera pas retournée.

Lors de l’utilisation du prédicat CONTAINING dans les termes de recherche des requêtes DML, l’optimiseur Firebird ne peut pas utiliser un index sur la colonne recherchée.

Recherche de sous-chaînes à l’aide du prédicat CONTAINING.

Recherchez les projets qui contiennent la chaîne “Map” dans leur nom :

SELECT *
FROM PROJECT
WHERE PROJ_NAME CONTAINING 'map';

Dans ce cas, deux lignes avec les noms “AutoMap” et “MapBrowser port” seront retournées.

Example 1. Recherche dans une date à l’aide du prédicat CONTAINING.

Une recherche d’enregistrements de modifications salariales dont la date contient le chiffre 84 (dans ce cas, les modifications qui ont eu lieu en 1984) :

SELECT *
FROM SALARY_HISTORY
WHERE CHANGE_DATE CONTAINING 84;
Voir aussi :

LIKE.

SIMILAR TO

Disponible en

DSQL, PSQL.

Syntaxe
string-expression [NOT] SIMILAR TO <pattern> [ESCAPE <escape-char>]

<pattern> ::= Expression régulière SQL
<escape-char> ::= symbole d'échappement

L’instruction SIMILAR TO vérifie si une chaîne de caractères correspond à un modèle d’expression régulière SQL. Contrairement à d’autres langages, le modèle doit correspondre à la totalité de la chaîne de caractères pour être exécuté avec succès - la correspondance d’une sous-chaîne ne suffit pas. Si l’un des opérandes est NULL, le résultat est NULL. Sinon, le résultat est TRUE ou FALSE.

Syntaxe des expressions régulières SQL

La syntaxe suivante définit le format d’une expression SQL régulière. Il s’agit d’une définition complète et correcte. Il est très formel et plutôt long et sera probablement déroutant pour ceux qui n’ont aucune expérience des expressions régulières. N’hésitez pas à la sauter et à commencer à lire la section suivante, Création d’expressions régulières qui utilise une approche simple à complexe.

<regular expression> ::= <regular term> ['|' <regular term> ...]

<regular term> ::= <regular factor> ...

<regular factor> ::= <regular primary> [<quantifier>]

<quantifier> ::= ? | * | + | '{' <m> [,[<n>]] '}'

<m>, <n> ::= des nombres positifs entiers, si les deux nombres sont présents, alors <m> <= <n>

<regular primary> ::=
    <character> | <character class> | %
  | (<regular expression>)

<character> ::= <escaped character> | <non-escaped character>

<escaped character> ::=
  <escape-char> <special character> | <escape-char> <escape-char>

<special character> ::= l'un des symboles []()|^-+*%_?{}

<non-escaped character> ::=
  tout caractère sauf <special character>
  et non équivalent <escape-char> (si c'est le cas)

<character class> ::=
    '_' | '[' <member> ... ']' | '[^' <non-member> ... ']'
  | '[' <member> ... '^' <non-member> ... ']'

<member>, <non-member> ::= <character> | <range> | <predefined class>

<range> ::= <character>-<character>

<predefined class> ::= '[:' <predefined class name> ':]'

<predefined class name> ::=
  ALPHA | UPPER | LOWER | DIGIT | ALNUM | SPACE | WHITESPACE
Création d’expressions régulières

Cette section présente les éléments et les règles de construction des expressions régulières SQL.

Symboles

Dans les expressions régulières, la plupart des caractères se représentent eux-mêmes, à l’exception des caractères spéciaux (special character):

[ ] ( ) | ^ - + * % _ ? { }

... et les symboles de contrôle (escaped character), s’ils sont définis.

Une expression régulière ne contenant aucun caractère spécial ou de contrôle ne correspond qu’à des chaînes de caractères totalement identiques (selon le tri utilisé). C’est-à-dire qu’il fonctionne exactement de la même manière que l’opérateur “=”:

'Apple' SIMILAR TO 'Apple' -- TRUE
'Apples' SIMILAR TO 'Apple' -- FALSE
'Apple' SIMILAR TO 'Apples' -- FALSE
'APPLE' SIMILAR TO 'Apple' -- en fonction du tri
Modèles

Les séquences SQL connues ‘_’ et ‘%’ correspondent respectivement à un caractère unique et à une chaîne de caractères de longueur quelconque :

'Birne' SIMILAR TO 'B_rne' -- TRUE
'Birne' SIMILAR TO 'B_ne' -- FALSE
'Birne' SIMILAR TO 'B%ne' -- TRUE
'Birne' SIMILAR TO 'Bir%ne%' -- TRUE
'Birne' SIMILAR TO 'Birr%ne' -- FALSE

Notez que le caractère'`%’ correspond également à une chaîne vide.

Classes de caractères

Un ensemble de caractères entre crochets définit une classe de caractères. Le caractère de la chaîne correspond à la classe du motif si le caractère est un élément de la classe :

'Citroen' SIMILAR TO 'Cit[arju]oen' -- TRUE
'Citroen' SIMILAR TO 'Ci[tr]oen' -- FALSE
'Citroen' SIMILAR TO 'Ci[tr][tr]oen' -- TRUE

Comme vous pouvez le voir sur la deuxième ligne, la classe ne comporte qu’un seul caractère, et non une séquence de caractères.

Deux caractères reliés par un trait d’union dans la définition de la classe définissent une plage. La plage pour le mappage actif comprend ces deux caractères d’extrémité et tous les caractères intermédiaires. Les plages peuvent être placées n’importe où dans la définition de la classe sans qu’il soit nécessaire d’utiliser des délimiteurs spéciaux pour garder les autres caractères dans la classe également.

'Datte' SIMILAR TO 'Dat[q-u]e' -- TRUE
'Datte' SIMILAR TO 'Dat[abq-uy]e' -- TRUE
'Datte' SIMILAR TO 'Dat[bcg-km-pwz]e' -- FALSE
Classes de caractères prédéfinies

Les classes de caractères prédéfinies suivantes peuvent également être utilisées dans la définition de la classe :

[:ALPHA:]

Lettres latines a…​z et A…​Z. Cette classe comprend également les caractères avec des signes diacritiques dans les tri insensibles aux accents.

[:DIGIT:]

Chiffres décimaux 0…​9.

[:ALNUM:]

Association [:ALPHA:] et [:DIGIT:].

[:UPPER:]

Capitales (majuscules) Lettres latines A…​Z. Inclut également les caractères minuscules dans le tri insensible à la casse et les signes diacritiques dans le tri insensible à l’accent.

[:LOWER:]

Les lettres latines a…​z (minuscules). Inclut également les caractères majuscules dans le tri insensible à la casse et les signes diacritiques dans le tri insensible à l’accent.

[:SPACE:]

Symbole d’espace (ASCII 32).

[:WHITESPACE:]

Tabulation horizontale (ASCII 9), saut de ligne (ASCII 10), tabulation verticale (ASCII 11), saut de page (ASCII 12), retour chariot (ASCII 13) et espace (ASCII 32).

Inclure une classe prédéfinie dans une déclaration SIMILAR TO a le même effet que d’inclure tous ses éléments. L’utilisation de classes prédéfinies n’est autorisée que dans la définition de la classe. Si vous n’avez besoin que d’un mappage vers une classe prédéfinie et rien d’autre, mettez une paire de parenthèses supplémentaire autour.

'Erdbeere' SIMILAR TO 'Erd[[:ALNUM:]]eere' -- TRUE
'Erdbeere' SIMILAR TO 'Erd[[:DIGIT:]]eere' -- FALSE
'Erdbeere' SIMILAR TO 'Erd[a[:SPACE:]b]eere' -- TRUE
'Erdbeere' SIMILAR TO '[[:ALPHA:]]' -- FALSE
'E' SIMILAR TO '[[:ALPHA:]]' -- TRUE

Si une définition de classe commence par un caractère d’insertion (^), tout ce qui le suit est exclu de la classe. Tous les autres caractères sont vérifiés.

'Framboise' SIMILAR TO 'Fra[^ck-p]boise' -- FALSE
'Framboise' SIMILAR TO 'Fr[^a][^a]boise' -- FALSE
'Framboise' SIMILAR TO 'Fra[^[:DIGIT:]]boise' -- TRUE

Si le caractère d’insertion (^) n’est pas au début de la séquence, la classe inclut tous les caractères qui le précèdent et exclut les caractères qui le suivent.

'Grapefruit' SIMILAR TO 'Grap[a-m^f-i]fruit' -- TRUE
'Grapefruit' SIMILAR TO 'Grap[abc^xyz]fruit' -- FALSE
'Grapefruit' SIMILAR TO 'Grap[abc^de]fruit' -- FALSE
'Grapefruit' SIMILAR TO 'Grap[abe^de]fruit' -- FALSE
'3' SIMILAR TO '[[:DIGIT:]^4-8]' -- TRUE
'6' SIMILAR TO '[[:DIGIT:]^4-8]' -- FALSE

Enfin, le caractère générique ‘_’ déjà mentionné est une classe de caractères à part entière, correspondant à n’importe quel caractère.

Quantificateurs

Un point d’interrogation ('``?'') immédiatement après un caractère ou une classe indique que l’élément précédent doit apparaître 0 ou 1 fois pour être apparié :

'Hallon' SIMILAR TO 'Hal?on' -- FALSE
'Hallon' SIMILAR TO 'Hal?lon' -- TRUE
'Hallon' SIMILAR TO 'Halll?on' -- TRUE
'Hallon' SIMILAR TO 'Hallll?on' -- FALSE
'Hallon' SIMILAR TO 'Halx?lon' -- TRUE
'Hallon' SIMILAR TO 'H[a-c]?llon[x-z]?' -- TRUE

Un astérisque (‘*’) immédiatement après un caractère ou une classe indique que l’élément précédent doit apparaître 0 fois ou plus pour que la correspondance soit établie :

'Icaque' SIMILAR TO 'Ica*que' -- TRUE
'Icaque' SIMILAR TO 'Icar*que' -- TRUE
'Icaque' SIMILAR TO 'I[a-c]*que' -- TRUE
'Icaque' SIMILAR TO '_*' -- TRUE
'Icaque' SIMILAR TO '[[:ALPHA:]]*' -- TRUE
'Icaque' SIMILAR TO 'Ica[xyz]*e' -- FALSE

Un signe plus (‘+’) immédiatement après un caractère ou une classe indique que l’élément précédent doit apparaître 1 fois ou plus pour que la correspondance soit établie :

'Jujube' SIMILAR TO 'Ju_+' -- TRUE
'Jujube' SIMILAR TO 'Ju+jube' -- TRUE
'Jujube' SIMILAR TO 'Jujuber+' -- FALSE
'Jujube' SIMILAR TO 'J[jux]+be' -- TRUE
'Jujube' SIMILAR TO 'J[[:DIGIT:]]+ujube' -- FALSE

Si un caractère ou une classe est accompagné(e) d’un nombre entre crochets (‘{’ et ‘}’), l’élément doit être répété exactement ce nombre de fois pour être apparié :

'Kiwi' SIMILAR TO 'Ki{2}wi' -- FALSE
'Kiwi' SIMILAR TO 'K[ipw]{2}i' -- TRUE
'Kiwi' SIMILAR TO 'K[ipw]{2}' -- FALSE
'Kiwi' SIMILAR TO 'K[ipw]{3}' -- TRUE

Si un nombre est suivi d’une virgule (‘,’), l’élément doit être répété au moins ce nombre de fois pour être mis en correspondance :

'Limone' SIMILAR TO 'Li{2,}mone' -- FALSE
'Limone' SIMILAR TO 'Li{1,}mone' -- TRUE
'Limone' SIMILAR TO 'Li[nezom]{2,}' -- TRUE

Si les accolades contiennent deux nombres (m et n) séparés par une virgule et que le deuxième nombre est supérieur au premier, l’élément doit être répété au moins m fois et pas plus de n fois pour correspondre :

'Mandarijn' SIMILAR TO 'M[a-p]{2,5}rijn' -- TRUE
'Mandarijn' SIMILAR TO 'M[a-p]{2,3}rijn' -- FALSE
'Mandarijn' SIMILAR TO 'M[a-p]{2,3}arijn' -- TRUE

Les quantors ‘ ? ’ , ‘*’ et ‘+’ sont des abréviations de {0,1}, {0,} et {1,} respectivement.

Le terme OR

Dans les conditions d’expression régulière, vous pouvez utiliser l’opérateur OR ‘|’. Une correspondance a eu lieu si la chaîne de paramètres correspond à au moins une des conditions :

'Nektarin' SIMILAR TO 'Nek|tarin' -- FALSE
'Nektarin' SIMILAR TO 'Nektarin|Persika' -- TRUE
'Nektarin' SIMILAR TO 'M_+|N_+|P_+' -- TRUE
Sous-expressions

Une ou plusieurs parties d’une expression régulière peuvent être regroupées en sous-expressions (également appelées sous-masques). Pour ce faire, mettez-les entre parenthèses. (‘(’ et ‘)’):

'Orange' SIMILAR TO 'O(ra|ri|ro)nge' -- TRUE
'Orange' SIMILAR TO 'O(r[a-e])+nge' -- TRUE
'Orange' SIMILAR TO 'O(ra){2,4}nge' -- FALSE
'Orange' SIMILAR TO 'O(r(an|in)g|rong)?e' -- TRUE
Caractère spécial d’échappement

Pour exclure les caractères spéciaux (que l’on trouve souvent dans les expressions régulières) du processus de correspondance, ils doivent être échappés. Il n’y a pas de caractères d’échappement spéciaux par défaut — ils sont définis par l’utilisateur si nécessaire :

'Peer (Poire)' SIMILAR TO 'P[^ ]+ \(P[^ ]+\)' ESCAPE '\' -- TRUE
'Pera [Pear]' SIMILAR TO 'P[^ ]+ #[P[^ ]+#]' ESCAPE '#' -- TRUE
'Paron-Appledryck' SIMILAR TO 'P%$-A%' ESCAPE '$' -- TRUE
'Parondryck' SIMILAR TO 'P%--A%' ESCAPE '-' -- FALSE

IS DISTINCT FROM

Disponible en

DSQL, PSQL.

Syntaxe
<operand1> IS [NOT] DISTINCT FROM <operand2>

Deux opérandes sont considérés comme DISTINCT (différents) s’ils ont des valeurs différentes, ou si l’un d’eux est NULL et l’autre non. Elles sont considérées comme NOT DISTINCT (égales) si elles ont les mêmes valeurs ou si elles sont toutes deux NULL.

L’option IS [NOT] DISTINCT FROM renvoie toujours VRAI ou FAUX et jamais UNKNOWN (NULL) (valeur inconnue). En revanche, les opérateurs “=” et “<>” renvoient UNKNOWN (NULL) si l’un ou les deux opérandes sont NULL.

Table 1. Les résultats des différents opérateurs de comparaison

Caractéristiques de l’opérande

Les résultats des différents opérateurs

=

IS NOT DISTINCT FROM

<>

IS DISTINCT FROM

Mêmes valeurs

TRUE

TRUE

FALSE

FALSE

Valeurs différentes

FALSE

FALSE

TRUE

TRUE

les deux NULL

UNKNOWN

TRUE

UNKNOWN

FALSE

un NULL et l’autre non NULL

UNKNOWN

FALSE

UNKNOWN

TRUE

Example 1. Utilisation d’un prédicat IS [NOT] DISTINCT FROM
SELECT ID, NAME, TEACHER
FROM COURSES
WHERE START_DAY IS NOT DISTINCT FROM END_DAY

IF (NEW.JOB IS DISTINCT FROM OLD.JOB) THEN
  POST_EVENT 'JOB_CHANGED';

Logique IS [NOT]

Disponible en

DSQL, PSQL.

Syntaxe
<value> IS [NOT] {TRUE | FALSE | UNKNOWN}

L’opérateur IS vérifie que l’expression du côté gauche correspond à la valeur logique du côté droit. L’expression du côté gauche doit être de type logique, sinon une erreur sera lancée.

Pour un type de données logique, le prédicat IS [NOT] UNKNOWN est équivalent à IS [NOT] NULL.

Note
Note:

Seuls les littéraux TRUE, FALSE, UNKNOWN peuvent être utilisés dans le côté droit du prédicat, mais pas les expressions.

Example 1. Utilisation de l’opérateur IS avec un type de données logique
-- Vérifier la valeur FALSE
SELECT * FROM TBOOL WHERE BVAL IS FALSE
ID           BVAL
============ =======
2            <false>
-- Vérifier la valeur UNKNOWN
SELECT * FROM TBOOL WHERE BVAL IS UNKNOWN
ID           BVAL
============ =======
3            <null>

IS [NOT] NULL

Disponible en

DSQL, PSQL.

Syntaxe
<value> IS [NOT] NULL

Comme NULL n’est pas une valeur, ces opérateurs ne sont pas des opérateurs de comparaison. L’opérateur IS [NOT] NULL vérifie que l’expression du côté gauche a une valeur (IS NOT NULL) ou n’a pas de valeur. (IS NULL)

Example 1. Utilisation d’un prédicat IS [NOT] NULL

Recherche des enregistrements de vente pour lesquels aucune date d’expédition n’a été définie :

SELECT *
FROM SALES
WHERE SHIP_DATE IS NULL;

Prédicats d’existence

Ce groupe de prédicats comprend des prédicats qui utilisent des sous-requêtes et passent des valeurs pour toutes sortes d’instructions dans les conditions de recherche. Les prédicats d’existence sont appelés ainsi parce qu’ils vérifient l’existence ou la non-existence des résultats des sous-requêtes de différentes manières.

EXISTS

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
[NOT] EXISTS (<select_stmt>)

Le prédicat EXISTS utilise la sous-requête comme argument. Si le résultat de la sous-requête contient au moins une entrée, le prédicat est évalué comme vrai (TRUE), sinon le prédicat est évalué comme faux (FALSE).

Le résultat d’une sous-requête peut contenir plusieurs colonnes, puisque les valeurs ne sont pas vérifiées, mais que seul le fait qu’il y ait des lignes du résultat est enregistré. Ce prédicat ne peut prendre que deux valeurs : VRAI et FAUX.

Le prédicat NOT EXISTS renvoie FALSE si le résultat de la sous-requête contient au moins une entrée, sinon le prédicat renvoie TRUE.

Example 1. Prédicat EXISTS

Trouvez les employés qui ont des projets.

SELECT *
FROM employee
WHERE EXISTS (SELECT *
              FROM
                employee_project ep
              WHERE
                ep.emp_no = employee.emp_no)
Example 2. Prédicat NOT EXISTS

Trouvez les employés qui n’ont pas de projets.

SELECT *
FROM employee
WHERE NOT EXISTS (SELECT *
                  FROM
                    employee_project ep
                  WHERE
                    ep.emp_no = employee.emp_no)

IN

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
<value> [NOT] IN (<select_stmt> | <value_list>)

<value_list> ::= <value_1> [, <value_2> ...]

Le prédicat IN vérifie si la valeur de l’expression à gauche est présente dans l’ensemble des valeurs spécifiées à droite. L’ensemble des valeurs ne peut pas dépasser 1500 éléments. Le prédicat IN peut être réécrit sous la forme équivalente suivante :

(<value> = <value_1> [OR <value> = <value_2> ...])

Lorsque vous utilisez le prédicat IN dans les termes de recherche des requêtes DML, l’optimiseur de Firebird peut utiliser un index sur la colonne recherchée s’il est défini.

Dans la deuxième forme, le prédicat IN vérifie si la valeur de l’expression de gauche est présente (ou absente, lorsqu’on utilise NOT IN) dans le résultat de la sous-requête de droite. Le résultat de la sous-requête ne peut contenir qu’une seule colonne, sinon une erreur sera émise. “count of column list and variable list do not match”.

Les requêtes utilisant le prédicat IN avec une sous-requête peuvent être réécrites en une requête similaire utilisant le prédicat EXISTS. Par exemple, la requête suivante :

SELECT
  model, speed, hd
FROM PC
WHERE
  model IN (SELECT model
            FROM product
            WHERE maker = 'A');

Vous pouvez réécrire une requête similaire en utilisant un prédicat. EXISTS:

SELECT
  model, speed, hd
FROM PC
WHERE
  EXISTS (SELECT *
          FROM product
          WHERE maker = 'A'
            AND product.model = PC.model);

Cependant, une requête utilisant NOT IN ne donnera pas toujours le même résultat qu’une requête NOT EXISTS. La raison en est que le prédicat EXISTS renvoie toujours TRUE ou FALSE, alors que le prédicat IN peut renvoyer NULL dans les cas suivants :

  1. Lorsque la valeur à vérifier est NULL et que la liste dans IN n’est pas vide.

  2. Lorsque la valeur à vérifier n’est pas une correspondance dans la liste IN et que l’une des valeurs est NULL.

Dans ces deux cas, le prédicat IN renverra NULL, tandis que le prédicat EXISTS correspondant renverra FALSE. Dans les conditions de recherche ou l’opérateur IF, les deux résultats indiquent `Fail' et sont traités de la même manière.

Cependant, sur les mêmes données, NOT IN retournera NULL, alors que EXISTS retournera TRUE, ce qui provoquera le résultat inverse.

C’est ce que montre l’exemple suivant.

Supposons que vous ayez une requête comme celle-ci :

-- Je cherche des gens qui ne sont pas nés le même jour que...
-- Des habitants célèbres de New York
SELECT P1.name AS NAME
FROM Personnel P1
WHERE P1.birthday NOT IN (SELECT C1.birthday
                          FROM Celebrities C1
                          WHERE C1.birthcity = 'New York');

On peut supposer qu’une requête utilisant un prédicat produira un résultat similaire NOT EXISTS:

-- Je cherche des gens qui ne sont pas nés le même jour que...
-- des habitants célèbres de New York
SELECT P1.name AS NAME
FROM Personnel P1
WHERE NOT EXISTS (SELECT *
                  FROM Celebrities C1
                  WHERE C1.birthcity = 'New York'
                    AND C1.birthday = P1.birthday);

Supposons qu’il n’y ait qu’un seul résident connu à New York et que sa date de naissance soit inconnue. Lorsque vous utilisez le prédicat EXISTS, la sous-requête qu’il contient ne produira pas de résultats car la comparaison des dates de naissance à NULL donnera UNKNOWN. Ainsi, le résultat du prédicat NOT EXISTS sera vrai pour chaque ligne de la requête principale. Alors que le résultat du prédicat NOT IN sera UNKNOWN et aucune ligne ne sera affichée.

Example 1. Prédicat IN

Trouver des employés avec des noms “Pete”, “Ann” et “Roger”:

SELECT *
FROM EMPLOYEE
WHERE FIRST_NAME IN ('Pete', 'Ann', 'Roger');
Example 2. Prédicat de recherche IN

Trouvez tous les ordinateurs pour lesquels il existe des modèles dont le fabricant commence par la lettre “A”:

SELECT
  model, speed, hd
FROM PC
WHERE
  model IN (SELECT model
            FROM product
            WHERE maker STARTING WITH 'A');
Voir aussi :

EXISTS.

SINGULAR

Disponible en

DSQL, PSQL, ESQL.

Syntaxe
[NOT] SINGULAR (<select_stmt>)

Le prédicat SINGULAR utilise la sous-requête comme argument et l’évalue comme vrai si la sous-requête retourne une et une seule ligne de résultat, sinon le prédicat est évalué comme faux. Le résultat de la sous-requête peut contenir plusieurs colonnes, puisque les valeurs ne sont pas vérifiées. Ce prédicat ne peut prendre que deux valeurs : vrai (TRUE) et faux (FALSE).

Example 1. Prédicat SINGULAR

Trouvez les employés qui n’ont qu’un seul projet.

SELECT *
FROM employee
WHERE SINGULAR (SELECT *
                FROM
                  employee_project ep
                WHERE
                  ep.emp_no = employee.emp_no)

Prédicats de sous-requêtes quantitatives

Un quantor est un opérateur logique qui spécifie le nombre d’objets pour lesquels une déclaration donnée est vraie. Il s’agit d’une quantité logique, et non d’une quantité numérique ; elle associe l’énoncé à l’ensemble des objets possibles. Ces prédicats sont basés sur les quantificateurs logiques formels de généralité et d’existence, qui sont reconnus par la logique formelle.

Dans les expressions de sous-requêtes, les prédicats quantitatifs permettent de comparer des valeurs individuelles aux résultats des sous-requêtes ; leur forme courante :

<value expression> <comparison operator> <quantifier> <subquery>

ALL

Disponible en

DSQL, PSQL.

Syntaxe
<value> <op> ALL (<select_stmt>)

En utilisant le quantificateur ALL, le prédicat est vrai si chaque valeur sélectionnée par la sous-requête satisfait à la condition du prédicat de la requête externe. Si la sous-requête ne renvoie aucune chaîne, le prédicat est automatiquement considéré comme vrai.

Example 1. Prédicat ALL

Ne faites resortir que les clients dont le score est supérieur à celui de chaque client de Paris.

SELECT *
FROM Customers
WHERE rating > ALL
      (SELECT rating
       FROM Customers
       WHERE city = 'Paris')
Important

Si la sous-requête renvoie un ensemble vide, alors le prédicat sera vrai pour chaque valeur gauchère, quel que soit l’opérateur. Cela peut sembler étrange et contradictoire, car dans ce cas, chaque valeur de la main gauche est traitée comme étant simultanément supérieure, inférieure, égale et inégale à toute valeur du courant de la main droite.

Cependant, ceci est normalement cohérent avec la logique formelle : si un ensemble est vide, alors le prédicat est vrai 0 fois, soit pour chaque ligne de l’ensemble.

ANY et SOME

Disponible en

DSQL, PSQL.

Syntaxe
<value> <op> {ANY | SOME} (<select_stmt>)

Ces deux quantificateurs ont un comportement identique. Apparemment, les deux sont introduits dans la norme SQL pour une utilisation interchangeable afin d’améliorer la lisibilité des déclarations. Lorsque le quantificateur ANY ou SOME est utilisé, le prédicat est vrai si l’une des valeurs sélectionnées par la sous-requête satisfait à la condition du prédicat de la requête externe. Si la sous-requête ne renvoie aucune chaîne, le prédicat est automatiquement considéré comme faux.

Example 1. Prédicat ANY

Ne faites resortir que les clients dont les scores sont supérieurs à ceux de tous les clients de Rome.

SELECT *
FROM Customers
WHERE rating > ANY
      (SELECT rating
       FROM Customers
       WHERE city = 'Rome')