PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 07/05/2020 21:44:14

databaser
Membre

Fonction to_char ne convertit pas integer en caractères

Bonjour,

Afin de convertir un integer en caractères, j'utilise la fonction to_char :

SELECT to_char(CP, '999') FROM MABASE.MATABLE WHERE CP = '75000'; 

Le résultat obtenu est une cellule contenant ###

Que se passe-t-il ? Rien n'est indiqué dans le tuto PGS. Merci big_smile

Hors ligne

#2 08/05/2020 09:07:44

rjuju
Administrateur

Re : Fonction to_char ne convertit pas integer en caractères

Bonjour,


Il vous faut utiliser au moins autant de '9' que de nombre de caractère dans le champ.  Puisqu'il s'agit apparemment d'un code postal, c'est donc 5 mais vous pourriez en mettre pus.  Comme indiqué dans la documentation en utilisant '9' plutôt que '0' les chiffres non significatifs seront tronqués de toutes façons :

# select to_char(75000, '99999999999999999');
      to_char       
--------------------
              75000
(1 row)

Hors ligne

#3 08/05/2020 12:46:01

databaser
Membre

Re : Fonction to_char ne convertit pas integer en caractères

Merci rjuju. Effectivement, j'ai souvenir de l'avoir lu dans la doc mais hier je n'ai pas trouvé. Je regarderai à nouveau.

Petit souci : je compare deux CP, CPA et CPB, sur le CPB j'applique le to_char.
Dans le résultat, il n'y a pas de correspondance faite entre les CP. Alors que je sais que les deux tables ont des CP en commun. Donc pourquoi PGS refuse-t-il ?

CPA est enregistrée comme une char(8) dans ma table. J'ai fait un trim(CP) pour m'assurer qu'il n'y a pas d'espace après les 5 caractères du CP.
Lors de l'application du char_to, CPB apparaît en text dans le résultat (le type de variable est visible dans le nom de la colonne de résultat). Pourquoi n'est-ce pas une charvar ou au mieux un char(5) puisque je suppose que tous les CP sont de 5 caractères ?

Autre question : j'ai utilisé un char_to pour une autre variable numérique en l'indiquant dans le SELECT du code, afin de ne pas alourdir le "ON + condition". Dans la condition, j'ai utilisé de la variable. Mon code marche.
Par contre, si je fais la même chose avec le char_to pour le CP (donc dans le SELECT puis utilisation du CP dans la condition de la requête), PGS renvoie une erreur. Si je mets le char_to dans la condition directement, le code marche mais la colonne du résultat pour CPB est vide -> d'où les questions ci-haut.
Donc pourquoi le char_to au niveau du SELECT marche dans un cas et pas dans l'autre ?
Merci!

Hors ligne

#4 08/05/2020 14:45:46

gleu
Administrateur

Re : Fonction to_char ne convertit pas integer en caractères

Donc pourquoi PGS refuse-t-il ?

Impossible à dire sans un exemple complet.

CPA est enregistrée comme une char(8) dans ma table. J'ai fait un trim(CP) pour m'assurer qu'il n'y a pas d'espace après les 5 caractères du CP.
Lors de l'application du char_to, CPB apparaît en text dans le résultat (le type de variable est visible dans le nom de la colonne de résultat). Pourquoi n'est-ce pas une charvar ou au mieux un char(5) puisque je suppose que tous les CP sont de 5 caractères ?

Parce que toutes les fonctions *trim renvoient le type de données text :

? postgres=# \df *trim
                          List of functions
┌────────────┬───────┬──────────────────┬─────────────────────┬──────┐
│   Schema   │ Name  │ Result data type │ Argument data types │ Type │
├────────────┼───────┼──────────────────┼─────────────────────┼──────┤
│ pg_catalog │ btrim │ bytea            │ bytea, bytea        │ func │
│ pg_catalog │ btrim │ text             │ text                │ func │
│ pg_catalog │ btrim │ text             │ text, text          │ func │
│ pg_catalog │ ltrim │ text             │ text                │ func │
│ pg_catalog │ ltrim │ text             │ text, text          │ func │
│ pg_catalog │ rtrim │ text             │ text                │ func │
│ pg_catalog │ rtrim │ text             │ text, text          │ func │
└────────────┴───────┴──────────────────┴─────────────────────┴──────┘
(7 rows)

Autre question : j'ai utilisé un char_to pour une autre variable numérique en l'indiquant dans le SELECT du code, afin de ne pas alourdir le "ON + condition". Dans la condition, j'ai utilisé de la variable. Mon code marche.
Par contre, si je fais la même chose avec le char_to pour le CP (donc dans le SELECT puis utilisation du CP dans la condition de la requête), PGS renvoie une erreur. Si je mets le char_to dans la condition directement, le code marche mais la colonne du résultat pour CPB est vide -> d'où les questions ci-haut.
Donc pourquoi le char_to au niveau du SELECT marche dans un cas et pas dans l'autre ?

Idem à la première réponse, impossible à répondre sans cas complet. Requête, résultat, message d'erreur, ... Bref, le truc habituel.


Guillaume.

Hors ligne

#5 11/05/2020 18:28:37

databaser
Membre

Re : Fonction to_char ne convertit pas integer en caractères

Bonjour,

Merci, voici les éléments demandés :
Mon objectif : jointure entre TABLE1 et TABLE2. Left outer join est bon, c'est le to_char qui coince.

SELECT t1.ADRESSE, t1.CPA,  t2.NOMVOIE, to_char(t2.NUMERO, '999'), to_char(t2.CPB, '99999')
FROM BASE.TABLE1 t1 LEFT OUTER JOIN BASE.TABLE2 t2 ON t1.ADRESSE = (t2.NUMERO || ' ' || t2.NOMVOIE) AND t1.CPA =  to_char(t2.CPB, '99999')
ORDER BY f.ADRESSE;

Description du résultat : 5 colonnes dont les noms sont celles citées dans le SELECT (ADRESSE, CPA, etc)
ADRESSE contient toutes les lignes de TABLE1 ainsi que les CPA associées. Les colonnes associées à TABLE2 contiennent toutes la mention "[null]" càd qu'elles sont vides. Bien sûr le nom des deux colonnes avec la fonction to_char sont nommées "to_char", et type "text". Il n'y a pas de souci dans tout ça.

Le problème, comme expliqué c'est pourquoi n'ai-je pas les colonnes associées à TABLE2 remplies ?

Si je retire la 2ème partie de la condition et ne demande que :

FROM BASE.TABLE1 t1 LEFT OUTER JOIN BASE.TABLE2 t2 ON t1.ADRESSE = (t2.NUMERO || ' ' || t2.NOMVOIE)

Résultat : mêmes colonnes que la 1ère requête. Cette fois-ci, il y a bien sûr plus de 500 lignes : correct. Surtout, les colonnes NOMVOIE, NUMERO, et CPB sont remplies.

Comment faire pour faire marcher la 1ère requête. Merci smile

Dernière modification par databaser (11/05/2020 18:31:37)

Hors ligne

#6 11/05/2020 21:50:09

pifor
Membre

Re : Fonction to_char ne convertit pas integer en caractères

Voici une explication possible:

                    Table "public.t"
 Column |     Type     | Collation | Nullable | Default 
--------+--------------+-----------+----------+---------
 cpa    | character(8) |           |          | 
 cpb    | integer      |           |          | 

insert into t values('12345', 12345);
INSERT 0 1
select cpa, cpb, length(cpa) as l_cpa, length(to_char(cpb,'99999')) as l_cpb, length(trim(to_char(cpb,'99999'))) as lt_cpb from t;
   cpa    |  cpb  | l_cpa | l_cpb | lt_cpb 
----------+-------+-------+-------+--------
 12345    | 12345 |     5 |     6 |      5
(1 row)

select cpa = to_char(cpb,'99999') from t;
 ?column? 
----------
 f
(1 row)

select cpa = trim(to_char(cpb,'99999')) from t;
 ?column? 
----------
 t
(1 row)

La conversion avec TO_CHAR réserve un caractère pour le signe (un espace si le nombre est positif) et le test d'égalité retourne faux.
L'utilisation de TRIM supprime ce caractère et le test d'égalité retourne vrai.


Pierre

Hors ligne

Pied de page des forums