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

#1 09/05/2018 17:31:49

databaser
Membre

longueur des variables

Bonjour,

J'aimerais créer des variables de la longueur maximale de la chaîne de caractères la plus longue pour chaque variable.

Je mesure cela avec char_length la longueur des variables (qui sont toutes de type chaîne de caractères même si ce sont des chiffres. C'est dû au fichier source. Par la suite, je vais changer les types des numériques en numérique). Je peux faire char_length car j'ai mis longueur = 255 pour toutes les variables mais je vais changer ces longueurs.

1/ Certains caractères comme "oe" occuperaient plusieurs octets. Donc comment connaître la vraie longueur de ma variable puisque char_length ne prend pas en compte ces caractères ?

2/ Est-ce une bonne démarche ? Je fais cela pour stocker moins (je me dis que si on mets longueur 255, cela prend de la place).
Pensez-vous que ma démarche soit naïve ?
Je n'ai rien trouvé dans la doc de PGS 10.

Merci tongue

Dernière modification par databaser (09/05/2018 17:44:10)

Hors ligne

#2 09/05/2018 20:45:07

rjuju
Administrateur

Re : longueur des variables

Je n'ai pas vraiment compris la question, mais peut être que ces fonctions peuvent vous aider :

# select char_length('œ'), length('œ'), octet_length('œ');
 char_length | length | octet_length 
-------------+--------+--------------
           1 |      1 |            2
(1 row)

Hors ligne

#3 10/05/2018 13:13:08

dverite
Membre

Re : longueur des variables

Je fais cela pour stocker moins (je me dis que si on mets longueur 255, cela prend de la place).

Avec le type varchar(N), la place n'est pas réservée à l'avance dans le stockage, et ça ne fait pas gagner de place
de mettre un N le plus petit possible.

Avec le type char(N) elle est réservée à l'avance mais surtout la chaîne est complétée par des espaces à droite avec un comportement bien particulier dans les comparaisons, voir la doc
https://docs.postgresql.fr/10/datatype-character.html

Ca n'est que dans le cas de char(N) que ça peut être intéressant de réduire le N.

Il faut savoir aussi que l'unité de cette quantité N est le caractère, pas l'octet.

Hors ligne

#4 10/05/2018 17:47:44

databaser
Membre

Re : longueur des variables

Merci, Julien smile  Deux choses bizarres :

1/dans une table, une variable dont la longueur déclarée dans CREATE TABLE, est CODE char(10) (10 est un chiffre arbitraire) a :
un max(char_length) = 10 et min(char_length)=9. En principe, ce code a une longueur de 9 caractères.
Donc, pour trouver quelles lignes ont une longueur de 10, j'écris :

 SELECT CODE
FROM BD.TABLE
WHERE LENGTH(CODE) >9; 

Résultat : une ligne avec un code qui compte... 9 caractères! Pourquoi ce résultat ? Il n'y a aucun caractère spécial dans le code renvoyé (d'ailleurs, c'est un code avec des chiffres mais enregistré comme chaîne de caractères.) A noter : ce résultat se trouve à la ligne 1 de la table.
Ses : min(octet_length) = 10 et max(octet_length)=12. Pourquoi cette différence entre le max et le min ? A priori, tous les codes ont longueur de 9.


2/ Est-ce que le octet_length marche vraiment ? Je vous explique : ex :

Dans une table différente de ma question 1/, j'importe mes données avec une COPY FROM et par ex dans CREATE TABLE, j'ai créé une variable "nom varchar (100)"
Puis, je vérifie la taille des noms :

SELECT max(length(TABLE.NOM))
FROM BD.TABLE;

Si max(length) donne 15, cela signifie que le nom le plus long est une chaîne de caractère de longueur 15.
max(octet_length) = 100. La différence entre ces deux max est bien trop grande!
Et ceci vaut pour toutes les variables, ex : si ADRESSE varchar (255), le max(octet_length) sera de 255.

3/qu'est-ce qu'exactement ces octets ? Je lis PGS 10 mais pas encore certaine de la réponse
Merci beaucoup!

Hors ligne

#5 10/05/2018 17:56:23

gleu
Administrateur

Re : longueur des variables

Tout à fait possible que le caractère supplémentaire dans l'exemple 1 soit invisible. Un espace au tout début ou en toute fin de la chaîne par exemple.

Pour le reste, c'est impossible de répondre sans les vraies requêtes et leurs résultats. Montrez un script SQL complet avec ces résultats par exemple. Ça part trop dans tous les sens, et j'avoue ne rien y comprendre smile


Guillaume.

Hors ligne

#6 10/05/2018 18:26:41

databaser
Membre

Re : longueur des variables

d'accord.

1/Pour l'espace, j'ai vérifié le contenu de la cellule, il n'y pas d'espace.
Julien, avez-vous remarqué que j'ai écris : ">9"="strictement supérieur à 9 caractères" et le résultat est un nom de 9 caractères sans aucun espace.

SELECT CODE
FROM BD.TABLE
WHERE LENGTH(CODE) >9;

Rq : LENGTH ou CHAR_LENGTH c'est le même résultat
Si je fais le même code avec LENGTH(CODE) =9, je retrouve toutes les autres lignes et elles, elles contiennent un espace après le code (du à : CREATE TABLE BD.TABLE
CODE char(10) )

De toute manière, max(char_length) ne compte que les caractères, pas les espaces, n'est-ce pas ? C'est pour cela que je vérifiais avec max(octet_length) qui prend en compte les espaces.


Pour la question 2/

CREATE TABLE BD.TABLE
(...)
NOMAFNOR char(42),
(...);
SELECT max(char_length(TABLE.NOMAFNOR))
FROM BD.TABLE;

Résultat : 32

SELECT max(octet_length(TABLE.NOMAFNOR))
FROM BD.TABLE;

Résultat : 42

Donc, le max(octet_length) = à l'espace que nous allouons à la variable lors de la création de la table.

Dernière modification par databaser (10/05/2018 20:22:10)

Hors ligne

#7 11/05/2018 11:49:14

rjuju
Administrateur

Re : longueur des variables

Je ne comprends absolument rien, et comme Guillaume sans exemple clair avec données à l'appui je ne vois pas comment aller plus loin.


Concernant

De toute manière, max(char_length) ne compte que les caractères, pas les espaces, n'est-ce pas ?

Je vais supposer que vous parlez de char_length(chaine), et la réponse est facile à trouver:

# select char_length(' ');
 char_length 
-------------
           1
(1 row)

Hors ligne

#8 11/05/2018 12:30:48

genamiga
Membre

Re : longueur des variables

Le type TEXT n'est-il pas fait pour cela ?

Hors ligne

#9 11/05/2018 13:09:20

dverite
Membre

Re : longueur des variables

Ses : min(octet_length) = 10 et max(octet_length)=12. Pourquoi cette différence entre le max et le min ? A priori, tous les codes ont longueur de 9.

Ce résultat, s'il est obtenu sur une colonne déclarée CHAR(10), prouve à 100% que vous avez des caractères qui ne sont ni des blancs ni des chiffres qui ont atterri dans le champ.

Pour voir exactement ce que sont ces caractères y compris s'ils sont invisibles à l'écran,
vous pouvez exécuter ce genre de requête qui extrait les caractères un par un avec leur code numérique:

select r,ascii(r) from
  (select regexp_split_to_table(code, '') as r from BD.TABLE where octet_length(code)=12) s;

Hors ligne

#10 14/05/2018 13:26:10

databaser
Membre

Re : longueur des variables

Merci pour toutes vos réponses, je regarde tout cela.

D'après la doc PGS10, vaut mieux mettre varchar tout simplement au lieu des char() pour une question de coût de stockage. Est-ce que dans ce cas, mettre une variable avec une contrainte de vérification CHECK "vérifier que la taille de la variable ne dépasse pas 5" à une VARCHAR, à la place d'une longueur donnée en utilisant CHAR(5), est judicieux ? Je ne pense pas mais je préfère vous demander votre avis. Merci smile

Hors ligne

#11 14/05/2018 15:49:39

dverite
Membre

Re : longueur des variables

Ce n'est pas la peine de mettre une contrainte via CHECK pour la longueur car un champ typé  VARCHAR(5) par exemple a déjà une contrainte sur le non-dépassement de 5 caractères.
Sinon oui c'est judicieux de remplacer CHAR(n) par VARCHAR(n). CHAR(n) complète avec des blancs à droite qui prennent de la place et n'ont aucun intérêt.

Hors ligne

#12 14/05/2018 19:04:31

databaser
Membre

Re : longueur des variables

@deverite : dans ce cas, pourquoi est-ce que PGS conserve le char() dans ses types de variables ? Autant le supprimer et pour des raisons d'interopérabilité avec un autre logiciel, varchar() de PGS correspondrait au char() de tous les autres logiciels...

Hors ligne

#13 15/05/2018 11:56:28

dverite
Membre

Re : longueur des variables

Char(N) est défini par le standard SQL comme un type de base depuis les débuts du SQL, au moins SQL-89, de même que Varchar(N).
Ne serait-qu'à cause de ça, il n'est pas question de l'enlever.
A ma connaissance ces deux types existent sur les autres SGBDs en général et ont grosso-modo le même comportement.

Hors ligne

Pied de page des forums