Aller au contenu

Sujets conseillés

Posté

Bonjour,

Selon la documentation MySQL, la fonction CONCAT_WS (= concat "with separator") ne prend pas en compte ni les valeurs nulles, ni les chaînes vides.

Doc mysql.com : concat_ws

Pourtant, chez moi (MySQL: 5.0.45), les valeurs nulles sont sautées, mais pas les chaînes vides.

Ex :

CONCAT_WS(', ', 'Mot', NULL, 'phrase', '', 'point.')

retourne : Mot, phrase, , point.

au lieu de (selon la doc) : Mot, phrase, point.

Chez vous, qu'est-ce qui est retourné ? Est-ce un problème de documentation, ou de version ? Si ça marche correctement chez vous (= conformément à la doc, c'est-à-dire sans la chaîne vide), merci de me préciser la version de votre mysql.

Merci pour vos réponses,

Posté

Le comportement que tu décris est le même chez moi. Les chaînes vides ne sont pas ignorées, mais les valeurs NULL le sont. Le problème n'en est pas réellement un, c'est une erreur de traduction du manuel en français apparemment :

CONCAT_WS() does not skip empty strings. However, it does skip any NULL values after the separator argument.
Source: MySQL 5.0 Reference Manual :: 11.4 String Functions

Préfère toujours la version originale des manuels si tu le peux car l'adage italien "Traduttore, traditore" (dont le sens est que toute traduction est une trahison) se vérifie bien souvent ;)

Posté

Vu le texte anglais j'ai du mal à croire à une erreur de traduction ; je pencherais plus pour un bug qu'ils ont décidé de "corriger" en modifiant la doc :P

Posté

Ou simplement que la documentation originale utilisée pour la traduction a été modifiée entre-temps parce qu'elle était erronée (et que la fonction est prévue pour fonctionner ainsi)... en même temps je ne vois pas en quoi cela change quelque chose le fond de mon propos.

Posté

Je n'ai pas dit non plus que ça changeait le "fond de ton propos" ; t'énerve pas ;)

Je précisait juste cela car ce n'est pas la première fois que MySQL fait le coup. Il y a eu changement de comportement entre les date et datetime il y a peu ; changement "non prévu". Suite aux rapports de bug il a juste été décidé de modifier la doc... sans annoncer pour autant ce changement "majeur" (on se retrouve quand même avec de nombreux scripts dont OpenAds qui ne fonctionnaient plus par exemple).

Bref : oui le problème vient bien d'une "incohérence" dans la version française, c'était bien vu. Mais je ne crois pas une seconde à l'erreur de traduction, mais plutôt à la tentative de "masquage" d'une bourde.

Posté
Je n'ai pas dit non plus que ça changeait le "fond de ton propos" ; t'énerve pas ;)

Ne t'inquiète pas, je ne risque pas de m'énerver pour si peu ;) Je cherchais à comprendre le but de ton intervention.

Tout dépend du mode de fonctionnement de l'équipe de développement, est-ce que les développeurs documentent leur travail correctement, est-ce que la documentation est rédigée en amont, en aval ou pendant le développement, etc... En plus c'est un développement Open-Source, donc s'il y a vraiment un problème on peut toujours aller au cur de celui-ci pour comprendre ce qui ne va pas.

Je n'ai pas connaissance du changement des types DATE et DATETIME dont tu parles, aurais-tu plus de détails à ce sujet s'il te plaît ?

Posté

Je ne retrouve pas le bug en question... on y a été confronté quand on est passé de MySQL 5.0.32 (debian etch) à la version 5.0.45 (backports). Nos scripts n'ont pas été impactés, mais il a fallu qu'on corrige OpenAds.

A priori le problème est le même que pour ce report, mais d'après ce qui est dit cela aurait été finalement corrigé dans la 5.0.51... sic.

Posté

En quoi est-ce que cela résout le problème (pour peu qu'il y en ait un, apparemment c'est le comportement normal de la fonction CONCAT_WS) ?

ISNULL (dans une requête) va retourner 0 ou 1... je ne vois pas où cela serait utile :huh:

Posté

Arf, en Sql Server, Tu peux faire ceci : "isnull(Monchamps, 'valeur si null')

Je ne me souviens plus de l'équivalent sous Mysql... :(

Posté

Tu peux certainement utiliser un IF, pas de problème de ce côté ... mais si ISNULL reste inutile, on souhaite détecter une chaîne vide, et ISNULL considère qu'une chaîne vide n'est pas NULL ;) Il faudrait utiliser IF et retourner NULL lorsque la comparaison est positive... et ceci pour chaque paramètre de la fonction CONCAT_WS à concaténer.

J'ai tendance à réaliser cela dans le code de l'application, pas sur le serveur de base de donnée, à moins qu'il y ait vraiment besoin de faire une tri ou une autre tâche sur le champ après concaténation. Je mets un exemple à titre indicatif, mais c'est peu représentatif vu que les valeurs sont fixes, ce serait plus représentatif avec des noms de champs ;) :

SELECT CONCAT_WS(', ', IF('Mot' <> '','Mot',NULL), IF(NULL <> '','Mot',NULL), IF('phrase' <> '','phrase',NULL), IF('' <> '','',NULL), IF('point.' <> '','point.',NULL));

À la sortie on se retrouve bien avec :

Mot, phrase, point.
Posté

Hum pareil avec des CASE (CASE WHEN Isnull(Champ) = 1 or Champ='') THEN ...) ou alors (CASE WHEN Champ+''='') THEN ...)

Posté

Ouais, en fait ni l'un ni l'autre... NULLIF est le plus approprié après avoir cherché un peu plus dans le manuel ... mais de toute façon toutes ces fonctions font la même chose ;)

Mais ça c'est plus court et propre :

SELECT CONCAT_WS(', ', NULLIF('Mot',''), NULLIF(NULL,''), NULLIF('phrase',''), NULLIF('',''), NULLIF('point.',''));

Posté

Whaou, et merci pour toutes ces réponses...

Au passage, j'en profite pour dire que, je crois, la fonction ISNULL s'appelle IFNULL en MySql

IFNULL('valeur_si_pas_Null', 'sinon_valeur')

Mais comme dit TheRec, elles se ressemblent toutes...

Depuis, j'ai aussi pensé à :

SELECT REPLACE(CONCAT_WS(', ', 'Mot', NULL, 'phrase', '', 'point.'), ', , ', ', ');

Et encore mieux :

SELECT REPLACE(CONCAT_WS(', ', TRIM('Mot'), TRIM(NULL), TRIM('phrase'), TRIM(''), TRIM('point.')), ', , ', ', ');

Et que je viens de découvrir une fonction qui se rapproche de CONCAT_WS : GROUP_CONCAT(`champ_a_concatener` SEPARATOR ',')

que cette fonction n'a rien à voir avec le "GROUP BY" sauf qu'elle est mal rangée dans la doc MySql (arrêtons de dire du mal... on est bien content de l'avoir cette doc quand même, non ?)

http://dev.mysql.com/doc/refman/5.0/fr/gro...-functions.html

Problème résolu ! Merci

Posté

Super ! Content d'avoir pu t'aider.

Tes solutions sont partiellement correcte, dans la mesure ou tu peux garantir qu'il n'y aura pas la chaîne ", , " dans les champs qui seront concaténés, sinon elle sera remplacée alors que ce n'était pas un champs de chaîne vide qui aura causé l'apparition de cette chaîne ;)

Pour information, ISNULL n'est pas équivalent à IFNULL. La première est une fonction qui retourne 0 ou 1 en évaluant si la valeur testée est NULL ou non. Et IFNULL vérifie si la valeur du premier paramètre est NULL, si c'est le cas la valeur du deuxième paramètre est retournée, sinon c'est la valeur du premier paramètre qui est retournée.

Encore une précision IS NULL n'est pas non plus équivalent à ISNULL, le premier est un opérateur et le second est une fonction ;)

Bonne continuation !

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...