2009-06-11 3 views
13

Ich habe PHP 5 Code, der auf eine MyISAM Tabelle auf MySQL 5 Server zugreift. Die Abfrage sieht wie folgt aus:MySQL gibt ein leeres Feld zurück: CONCAT (nonEmpty1, empty2, nonEmpty3) = NULL

SELECT CONCAT(fName1,' ',mName2,' ',lName3) AS userName 
    FROM users 
    WHERE level > 10 

Wenn kein MNAME in, gefüllt ist I-Ausgang erwarte wie „fname lname“, aber ich bin immer „“ (leere Zeichenkette) statt (die Anzahl der zurückgegebenen Zeilen ist richtig). Wo mache ich einen Fehler?

PHP-Code:

<?php 
$result = mysql_query($the_above_query); 
while ($result_row = mysql_fetch_assoc($result)) { 
    // do stuff with the name 
    // except I'm getting empty strings in $result_row['userName'] 
} 

relevanter Teil der Tabellenstruktur:

CREATE TABLE users { 
    /* -snip- */ 
    `fName1` varchar(50) default NULL,  
    `mName2` varchar(50) default NULL,  
    `lName3` varchar(50) default NULL,  
    `level` int(11) default 0,  
    /* -snip- */ 
} ENGINE=MyISAM DEFAULT CHARSET=utf8; 

(Auch ist auf diese Weise (Spalte Verkettung in MySQL) eine gute Idee, oder soll ich hole die Spalten PHP und ihnen dort beitreten?)


Stellt sich heraus, dass ich ein NULL zurückbekam; PHP behandelt eine zurückgegebene NULL und eine leere Zeichenfolge ("") in ähnlicher Weise, Sie müssten mit === vergleichen, um den Unterschied zu sehen.

Antwort

25

von Google: http://bugs.mysql.com/bug.php?id=480

[23. Mai 2003 04.32] Alexander Keremidarski

Vielen Dank für die Zeit nehmen, uns zu schreiben, aber das ist nicht ein Fehler. Prüfe die verfügbare Dokumentation zu http://www.mysql.com/documentation/ und den Anweisungen auf wie bei http://bugs.mysql.com/how-to-report.php

einen Fehler meldet Funktion Dies wird doccumented Verhalten von CONCAT().

Aus Handbuch Kapitel 6.3.2 String-Funktionen

CONCAT (str1, str2, ...) Gibt die Zeichenfolge, die die Argumente aus verketten führt. Gibt NULL zurück Argument ist NULL

Verwenden Sie stattdessen CONCAT_WS() oder umbrechen Sie NULLable-Parameter mit IFNULL() - Funktion.

Dokumentation und Nutzung für CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws

+0

Schöne Entdeckung auf 'CONCAT_WS()' – redolent

11

In MySQL in NULL beliebige Zeichenfolge auf einen Nullwert Ergebnisse verketten. Sie haben für NULL vor concatenate mit IFNULL zu überprüfen:

SELECT CONCAT(IFNULL(fName1,''),' ',IFNULL(mName2,''),' ',IFNULL(lName3,'')) AS userName 
FROM users 
WHERE level > 10 
16

Von MYSQL docs

CONCAT() gibt NULL zurück, wenn ein Argument NULL ist.

wollen Sie CONCAT_WS()

CONCAT_WS(separator,str1,str2,...) 

Aber beste Wette ist, verwenden, um es einfach zurück zu ziehen und php Ursache verwenden, wenn Sie ein anderes Format benötigen oder nur eines dieser Felder später werden Sie haben um einen weiteren db-Aufruf zu machen

+0

+1: und Dank! –

+0

+1 und großes Dankeschön - wusste nie, dass es das gab, aber ich brauche es heute Abend! – dadwithkids

3

Das war die Lösung, die ich mit der Antwort von Keeper und Ersatz entwickelt habe. System würde mir nicht erlauben, euch bis zu stimmen, obwohl :(

CONCAT_WS(IFNULL(ts_usr_nameDetails.first_name,''),' ',IFNULL(ts_usr_lib_connectionNameDetails.first_name,'')) AS composerName

Das für einige erstaunliche Ergebnisse erlaubt

+0

Wenn Sie CONCAT_WS verwenden und das Trennzeichen (erstes Argument) nicht NULL ist, müssen Sie IFNULL nicht verwenden. '" CONCAT_WS() überspringt keine leeren Strings. Es überspringt jedoch alle NULL-Werte nach dem Trennzeichen-Argument. Wenn das Trennzeichen NULL ist, ist das Ergebnis NULL. "' Siehe http://dev.mysql.com/doc/ refman/5.0/de/string-functions.html # function_concat-ws – dvb

1

Dies ist eine Antwort auf die Lösung oben @chocojosh und eine andere Frage hier beruht: MySQL/SQL: Update with correlated subquery from the updated table itself

Ich hatte ein ähnliches Problem, aber ich versuchte, eine Gruppe von group_concats zu concattieren und einige waren NULL, die die ganze Zeile als NULL verursacht.Das Ziel war es, Daten aus anderen Tabellen in einem einzigen Feld in der Haupttabelle zu platzieren um Volltextsuchen zu ermöglichen.

Hier ist das SQL, das funktioniert. Beachten Sie den ersten Parameter für concat_ws, den ich gemacht habe. Dies erlaubt Leerzeichen zwischen den Werten für das Volltextfeld.

Ich hoffe, das hilft jemandem.

update 
products target 
INNER JOIN 
(
    select p.id, 
    CONCAT_WS(
    ' ', 
     (select GROUP_CONCAT(field SEPARATOR ' ') from table1 where productId = p.id), 
     p.title,' ', 
     (select GROUP_CONCAT(field, ' ', descriptions SEPARATOR ' ') from table2 where productId = p.id), 
     (select GROUP_CONCAT(field SEPARATOR ' ') from table3 where productId = p.id), 
     (select GROUP_CONCAT(field, ' ', catno SEPARATOR ' ') from table4 where productId = p.id), 
     (select GROUP_CONCAT(field SEPARATOR ' ') from table5 where productId = p.id), 
     (select GROUP_CONCAT(field SEPARATOR ' ') from table6 where productId = p.id), 
     (select GROUP_CONCAT(field SEPARATOR ' ') from table7 where productId = p.id) 
    ) as ft 
    from products p 
) as source 
on target.id = source.id 
set target.fulltextsearch = source.ft 
1

Sie könnte auch die COALESCE() Funktion den ersten Nicht-Null-Wert zurück. Wie so:

SELECT CONCAT(fName1,COALESCE(CONCAT(' ',mName2,' '),' '),lName3) AS userName 
    FROM users 
    WHERE level > 10 

Dies würde auch setzen nur einen Raum, wenn es keinen Mittelweg Name und ein Raum war vor und nach, wenn gab es einen mittleren Namen.

Referenz für diese Funktion finden Sie unter: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce

+0

Dies ist die beste Antwort IMO, da Sie einfach eine Null in eine leere Zeichenfolge koaleszieren können: concat (address1, '', coalesce (unit, ''), ' ', Stadt,', ', Staat,' ', Postleitzahl) als Adresse – Jage

Verwandte Themen