FAQ FirebirdConsultez toutes les FAQ
Nombre d'auteurs : 6, nombre de questions : 205, dernière mise à jour : 15 septembre 2014 Ajouter une question
Cette faq a été réalisée à partir des questions fréquement posées sur les forums Firebird de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette F.A.Q. ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette F.A.Q. ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci
Sur ce, nous vous souhaitons une bonne lecture.
L'équipe Firebird de Developpez.com
- Comment récupérer les X premiers enregistrements ?
- Comment récupérer les X enregistrements après l'enregistrement Y ?
- Comment récupérer le nom des tables d'une base de données ?
- Comment obtenir la date et l'heure du serveur Firebird ?
- Comment obtenir le nombre d'enregistrements d'une requête sans l'exécuter ?
- Comment trouver les enregistrements en double ?
- Comment effacer des enregistrements en double (quand la table n'a pas de clé primaire) ?
- Comment intégrer un saut de ligne (CRLF) à une chaine en SQL?
- Comment éviter d'avoir des listes GROUP BY importantes quand on fait la jonction de plusieurs tables ?
- Comment convertir un BLOB en string?
- Dois-je mettre les identifiants en majuscules ?
- Pourquoi chaine + chaine ne fonctionne pas ?
- Pourquoi LIKE ne fonctionne pas avec le caractère de remplacement % au début?
- Pourquoi CURRENT_TIMESTAMP renvoie la même valeur pour toutes les lignes?
- Y a t-il une fonction comme DUMP en Oracle?
- Est-il possible d'utiliser un SELECT pour calculer des colonnes COMPUTED ?
- Comment mettre à jour des colonnes d'une table en utilisant les valeurs d'une autre table ?
- Comment fournir le nom d'une vue, procédure ou table à une procédure stockée ?
- Comment convertir un BLOB en string?
- Comment avoir le numéro d'enregistrement à l'intérieur d'un ensemble de données ?
- Quelle est la différence entre CHAR et VARCHAR?
Il faut utiliser le mot clé FIRST :
Code sql : | Sélectionner tout |
SELECT FIRST X Champ1, Champ2 .... FROM ....
Il faut utiliser les mots clés FIRST et SKIP :
Code sql : | Sélectionner tout |
SELECT FIRST X SKIP Y Champ1, Champ2 .... FROM ....
Pour cela il est nécessaire de lancer une requête sur les tables systèmes de notre base de données.
Code sql : | Sélectionner tout |
1 2 3 | select distinct RDB$RELATION_NAME from rdb$RELATION_FIELDS where RDB$VIEW_CONTEXT is null and RDB$SYSTEM_FLAG = 0; |
Il y a deux variables disponibles , CURRENT_DATE qui retourne la date courante et CURRENT_TIMESTAMP qui retourne la date et l'heure. Vous pouvez les utiliser dans les instructions SQL:
Code SQL : | Sélectionner tout |
insert into t1 values(10, CURRENT_TIMESTAMP);
Code SQL : | Sélectionner tout |
1 2 | select current_date, current_timestamp from rdb$database; |
Vous pouvez aussi utiliser ces variables en PSQL (langage des procédures stockées et triggers)
Code SQL : | Sélectionner tout |
1 2 3 4 5 6 7 | create procedure p1 as BEGIN if (current_timestamp > cast('2007-11-03' as timestamp)) then exception myerror; ... END |
Code SQL : | Sélectionner tout |
1 2 | select cast('now' as timestamp), cast('today' as date) from rdb$database |
La raison derrière ceci est l'atomicité d'une transaction, donc CURRENT_DATE et CURRENT_TIMESTAMP doivent fournir une certaine cohérence. Spécialement pour des systèmes tournant 24H/24 7J/7 il peut très bien arriver que la date change entre le début et la fin de la transaction.
Traduction réalisée depuis http://www.firebirdfaq.org/faq114/
Quelquefois vous voulez juste savoir combien d'enregistrements fournira une requête, sans pour autant les récupérer. Avec Firebird 2 et les tables dérivées c'est facile :
Code SQL : | Sélectionner tout |
SELECT COUNT(*) FROM ( votre requête );
Code SQL : | Sélectionner tout |
SELECT COUNT(*) FROM ( select * from employee where emp_no > 8 );
Par exemple :
Code SQL : | Sélectionner tout |
1 2 3 4 5 | create view my_employees as select * from employee where emp_no > 8; commit; SELECT COUNT(*) FROM my_employees; commit; drop view my_employees; |
Vous pouvez vouloir ajouter un index UNIQUE sur le champ d'une table (par exemple le champ ID) mais vous avez besoin pour cela de trouver et détruire les enregistrements en double avant. Voici une requête pour les trouver :
Code SQL : | Sélectionner tout |
1 2 3 4 | select id, count(*) from t1 group by id having count(*) > 1; |
Vous pouvez utiliser la 'clé secrète' RDB$DB_KEY de Firebird. RDB$DB_KEY est un champ 'caché' qui identifie chaque ligne dans une instruction SQL. Par exemple, si vous avez une table TABLE1 sans clé primaire, avec les colonnes COL1 et COL2 qui sont les mêmes , vous pourrez effacer les lignes 'extras' ainsi :
Code SQL : | Sélectionner tout |
1 2 3 4 5 | DELETE FROM TABLE1 t1 WHERE EXISTS ( SELECT 1 FROM TABLE1 t2 WHERE t1.COL1 = t2.COL1 and t1.COL2 = t2.COL2 AND t2.RDB$DB_KEY > t1.RDB$DB_KEY ); |
Traduction réalisée depuis http://www.firebirdfaq.org/faq301/
Il y a plusieurs manières de faire, par exemple, ceci fonctionne :
Code SQL : | Sélectionner tout |
1 2 3 4 | declare variable s varchar(20); ... s = 'Ceci est la ligne un. Ceci est la ligne deux.'; |
Code SQL : | Sélectionner tout |
c = 'Ceci est la ligne un.'||ASCII_CHAR(13)||ASCII_CHAR(10)||'Ceci est la ligne deux.';
Traduction réalisée depuis http://www.firebirdfaq.org/faq132/
Supposons que vous ayez une requête d'agrégat simple , sur la base exemple employee , qui fournit le nombre d'employés pour chaque projet :
Code SQL : | Sélectionner tout |
1 2 3 | SELECT ep.PROJ_ID, count(*) FROM EMPLOYEE_PROJECT ep GROUP BY ep.PROJ_ID; |
Code SQL : | Sélectionner tout |
1 2 3 4 | SELECT ep.PROJ_ID, p.PROJ_NAME, p.PRODUCT, count(*) FROM EMPLOYEE_PROJECT ep JOIN PROJECT p on ep.PROJ_ID = p.PROJ_ID GROUP BY ep.PROJ_ID, p.PROJ_NAME, p.PRODUCT; |
Code SQL : | Sélectionner tout |
1 2 3 4 | SELECT ep.PROJ_ID, MAX(p.PROJ_NAME), MAX(p.PRODUCT), count(*) FROM EMPLOYEE_PROJECT ep JOIN PROJECT p on ep.PROJ_ID = p.PROJ_ID GROUP BY ep.PROJ_ID |
Une conversion directe n'est pas possible sans utiliser une UDF, mais vous pouvez extraire du texte en utilisant la fonction SUBSTRING .
Code sql : | Sélectionner tout |
1 2 | DECLARE VARIABLE v1 VARCHAR(32000); SELECT SUBSTRING(nom_colonne_blob1 FROM 1 FOR 32000) FROM table1 INTO v1; |
Plusieurs sous-couches d'accès aux bases de données permettent de récupérer les données BLOB en chaine, et ce directement. Par exemple, en PHP vous pouvez utiliser:
Code php : | Sélectionner tout |
$row = ibase_fetch_assoc($qry, IBASE_TEXT);
Traduction réalisée depuis http://www.firebirdfaq.org/faq250/
Réponse courte : Non , pas besoin.
Réponse longue :
Firebird vous permet des identifiants en majuscules, minuscules ou les deux car il ignore la casse (case insensitive).
Code SQL : | Sélectionner tout |
1 2 3 | SELECT * FROM Employee; SELECT * FROM EMPLOYEE; SELECT * FROM employee; |
Si vous voulez vraiment utiliser des minuscules (et non seulement des majuscules) vous devrez mettre des doubles apostrophes pour chaque identifiant. Attention, une fois fait, vous devrez tout le temps le faire.
Code SQL : | Sélectionner tout |
1 2 3 | SELECT * FROM "Employee"; SELECT * FROM "EMPLOYEE"; SELECT * FROM "employee"; |
Vous pouvez aussi utiliser les guillemets pour stocker des caractères autrement illégaux tels que point, virgule, double point , point d'interrogation et caractères nationaux (non ASCII), ou un mot clé SQL réservé (par exemple pour avoir une colonne nommée User ou Date ).
Certains utilisateurs préfèrent ne pas compliquer les choses et n'utilisent aucune apostrophe , d'autres adorent avoir une casse mélangée et ne sont pas gênés par les doubles apostrophes. La plupart des outils d'administration (FlameRobin inclus) ont une option de configuration pour répondre a vos besoins : apostrophes seulement si besoin , ou apostrophes tout le temps.
Traduction réalisée depuis http://www.firebirdfaq.org/faq76/
Si vous essayez d'écrire une expression telle que char + char ou varchar + varchar, ou si vous essayez d'ajouter une valeur chaine à une autre , vous obtiendrez un message d'erreur comme celui-ci :
expression evaluation not supported
La raison, le + n'est pas l'opérateur de concaténation de chaine en SQL standard , c'est ||.
Code SQL : | Sélectionner tout |
select first_name||' '||last_name from employee;
Pour contourner ce problème, utilisez la fonction COALESCE.
Prenez également en compte que, contrairement à certains autres systèmes de bases de données, Firebird suit les normes SQL, et que NULL n'est pas la même chose qu'une chaîne vide ''.
Traduction réalisée depuis http://www.firebirdfaq.org/faq21/
Vous pouvez avoir un problème de ce genre :
Code sql : | Sélectionner tout |
1 2 3 4 5 | CREATE TABLE t1 ( c1 CHAR(5) ); COMMIT; INSERT INTO t1 VALUES ('abcd'); SELECT * FROM t1 WHERE c1 LIKE '%cd'; |
Pour contourner ceci vous utiliserez un VARCHAR, ou retaillerez la colonne en utilisant les fonctions TRIM ou RTRIM
Code sql : | Sélectionner tout |
SELECT * FROM t1 WHERE RTRIM(c1) LIKE '%cd';
Traduction réalisée depuis http://www.firebirdfaq.org/faq309/
C'est ainsi conceptualisé. CURRENT_TIMESTAMP fournit la même valeur pour tout un ensemble d'instructions. Cela veut dire que CURRENT_TIMESTAMP aura la même valeur à l'intérieur d'un ensemble, et également durant l'exécution d'une procédure stockée et des différentes procédures pouvant être appelées par celle-ci .
Si vous voulez obtenir la 'vraie' heure plutôt que l'heure de l'exécution utilisez 'now' qui est une valeur spéciale.
Code sql : | Sélectionner tout |
1 2 | select cast('now' as timestamp) from ... |
Traduction réalisée depuis http://www.firebirdfaq.org/faq56/
Vous pouvez transformer le résultat dans le set de caractères OCTETS. C'est utilisé pour mettre en clair des données binaires et la plupart des clients (ISQL, FlameRobin, etc.) l'affichera en hexadécimal. Exemple:
Code sql : | Sélectionner tout |
1 2 | SELECT CAST('Firebird' AS VARCHAR(20) CHARACTER SET OCTETS) FROM RDB$DATABASE |
Code sql : | Sélectionner tout |
4669726562697264
Oui. Vous aurez besoin d'utiliser une double paire de parenthèses. Exemple:
Code sql : | Sélectionner tout |
1 2 | ALTER TABLE t1 ADD compteur_relation COMPUTED BY ( (SELECT COUNT(*) FROM RDB$RELATIONS) ); |
Traduction réalisée depuis http://www.firebirdfaq.org/faq289/
La manière la plus courante en SQL est la suivante:
Code sql : | Sélectionner tout |
1 2 3 4 5 6 | UPDATE dest_table t1 SET field1 = (select field1 from src_table t2 where t2.pk = t1.pk), field2 = (select field2 from src_table t2 where t2.pk = t1.pk), ...etc. WHERE EXISTS (select 1 from src_table t2 where t2.pk = t1.pk) |
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | EXECUTE BLOCK AS DECLARE VARIABLE field1 type; DECLARE VARIABLE field2 type; ...etc. DECLARE VARIABLE pk type; BEGIN for select pk, field1, field2, ... from src_table into :pk, :field1, :field2, ... do update dest_table set field1 = :field1, field2 = :field2, ... where pk = :pk; END |
Outre le SQL direct, vous pouvez utiliser des outils tels que FBExport qui vous permettra une meilleure manipulation des erreurs (il sera plus facile de trouver la ligne exacte ainsi que la colonne qui empêche la mise à jour). Voici un exemple avec FBExport, premièrement exporter les données vers un fichier:
Code text : | Sélectionner tout |
fbexport -S -Q "select pk, field1, field2, ... from src_table" -F test.fbx
Ensuite les importer dans une autre table :
Code text : | Sélectionner tout |
fbexport -If -Q "update dest_table set field1 = :2, field2 = :3, ... where pk = :1" -F test.fbx
FBExport est un outil open source. Le téléchargement de la dernière version est ici
Traduction réalisée depuis http://www.firebirdfaq.org/faq323/
Vous pourriez avoir une procédure stockée qui fait quelque chose avec une table, mais dont le nom de cette table ne soit connu qu'à l'exécution. Vous pouvez faire cela avec un EXECUTE STATEMENT. Par exemple , nous voulons fournir le nom de la table dont nous voulons extraire le champ ID :
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | SET TERM !! ; CREATE PROCEDURE p1 ( TableName VARCHAR(32)) RETURNS ( id integer ) AS DECLARE VARIABLE stmt VARCHAR(1000); BEGIN stmt = 'select id from '||:TableName; for execute statement :stmt into :id do suspend; END; SET TERM ; !! |
Traduction réalisée depuis http://www.firebirdfaq.org/faq322/
Une conversion directe n'est pas possible sans utiliser une UDF, mais vous pouvez extraire du texte en utilisant la fonction SUBSTRING .
Code sql : | Sélectionner tout |
1 2 | DECLARE VARIABLE v1 VARCHAR(32000); SELECT SUBSTRING(nom_colonne_blob1 FROM 1 FOR 32000) FROM table1 INTO v1; |
Plusieurs sous-couches d'accès aux bases de données permettent de récupérer les données BLOB en chaine, et ce directement. Par exemple, en PHP vous pouvez utiliser:
Code php : | Sélectionner tout |
$row = ibase_fetch_assoc($qry, IBASE_TEXT);
Traduction réalisée depuis http://www.firebirdfaq.org/faq250/
Parfois vous devez fournir une requête SQL à un outil tiers ou à un composant, en souhaitant qu'elle renvoie le numéro de chaque ligne. Bien que cela soit facilement faisable via une variable temporaire dans une procédure stockée ou en utilisant un EXECUTE BLOCK, vous pouvez souhaiter cette numérotation au titre d'un simple SELECT .
Les variables de contexte de Firebird peuvent faire le travail pour vous . Voici une manière de faire proposée par Fabiano Bonin. Cet exemple montre toutes les tables et vues de la base de données :
Exemple pour les bases de données en Dialect 3 :
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 | SELECT rdb$get_context('USER_TRANSACTION', 'row#') as row_number, rdb$set_context('USER_TRANSACTION', 'row#', COALESCE(cast(rdb$get_context('USER_TRANSACTION', 'row#') as integer), 0) + 1), a.rdb$relation_name FROM rdb$relations a ORDER BY a.rdb$relation_name |
Code sql : | Sélectionner tout |
1 2 3 4 5 6 7 | SELECT rdb$get_context('USER_TRANSACTION', 'row#') as row_number, rdb$set_context('USER_TRANSACTION', 'row#', COALESCE(rdb$get_context('USER_TRANSACTION','row#'),0) + 1), a.rdb$relation_name FROM rdb$relations a ORDER BY a.rdb$relation_name |
Traduction réalisée depuis http://www.firebirdfaq.org/faq343/
La plus importante est que CHAR est rempli avec des espaces à droite alors que VARCHAR ne l'est pas. Par exemple, avec ceci :
Code sql : | Sélectionner tout |
1 2 3 4 5 | CREATE TABLE t1 ( v1 VARCHAR(4), c2 CHAR(4) ); INSERT INTO t1 (v1,c2) VALUES ('a', 'a'); |
Code sql : | Sélectionner tout |
1 2 | .. WHERE v1 = 'a' ..WHERE c2 = 'a' |
Traduction réalisée depuis http://www.firebirdfaq.org/faq237/
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.