lionel.a Posté 6 Avril 2008 Posté 6 Avril 2008 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,
TheRec Posté 6 Avril 2008 Posté 6 Avril 2008 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
Kioob Posté 6 Avril 2008 Posté 6 Avril 2008 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
TheRec Posté 6 Avril 2008 Posté 6 Avril 2008 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.
Kioob Posté 6 Avril 2008 Posté 6 Avril 2008 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.
TheRec Posté 6 Avril 2008 Posté 6 Avril 2008 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 ?
Kioob Posté 6 Avril 2008 Posté 6 Avril 2008 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.
Portekoi Posté 7 Avril 2008 Posté 7 Avril 2008 Bonjour, Ajoute un ISnull() pour contourner le problème. Bye Porteoi
TheRec Posté 7 Avril 2008 Posté 7 Avril 2008 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
Portekoi Posté 7 Avril 2008 Posté 7 Avril 2008 Arf, en Sql Server, Tu peux faire ceci : "isnull(Monchamps, 'valeur si null') Je ne me souviens plus de l'équivalent sous Mysql...
Portekoi Posté 7 Avril 2008 Posté 7 Avril 2008 Sous DB2, c'est coalesce mais c'est pas sa pour Mysql... bizarre, je trouve pas l'équivalent...
TheRec Posté 7 Avril 2008 Posté 7 Avril 2008 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.
Portekoi Posté 7 Avril 2008 Posté 7 Avril 2008 Hum pareil avec des CASE (CASE WHEN Isnull(Champ) = 1 or Champ='') THEN ...) ou alors (CASE WHEN Champ+''='') THEN ...)
TheRec Posté 7 Avril 2008 Posté 7 Avril 2008 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.',''));
lionel.a Posté 7 Avril 2008 Auteur Posté 7 Avril 2008 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
TheRec Posté 7 Avril 2008 Posté 7 Avril 2008 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 !
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant