Frage

Beschreibung:  die Abfrage ausgeführt hat tatsächlich vier Treffer, kann von unten sehen werden,  was ich getan habe ist concate nur die Einzelteile dann zurück,  aber unerwartet, es ist null.

Ich denke, der Code ist selbsterklärend:

DELIMITER |

DROP FUNCTION IF EXISTS get_idiscussion_ask|

CREATE FUNCTION get_idiscussion_ask(iask_id INT UNSIGNED) RETURNS TEXT DETERMINISTIC
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE body varchar(600);
  DECLARE created DATETIME;
  DECLARE anonymous TINYINT(1);
  DECLARE screen_name varchar(64);
  DECLARE result TEXT;
  DECLARE cur1 CURSOR FOR SELECT body,created,anonymous,screen_name from idiscussion left join users on idiscussion.uid=users.id where idiscussion.iask_id=iask_id;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  SET result = '';
  OPEN cur1;
  REPEAT
    FETCH cur1 INTO body, created, anonymous, screen_name;
    SET result = CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>');
  UNTIL done END REPEAT;
  CLOSE cur1;

  RETURN result;
END |

DELIMITER ;

mysql> DELIMITER ;
mysql> select get_idiscussion_ask(1);
+------------------------+
| get_idiscussion_ask(1) |
+------------------------+
| NULL                   |
+------------------------+
1 row in set (0.01 sec)



mysql> SELECT body,created,anonymous,screen_name from idiscussion left join users on idiscussion.uid=users.id where idiscussion.iask_id=1;
+------+---------------------+-----------+-------------+
| body | created             | anonymous | screen_name |
+------+---------------------+-----------+-------------+
| haha | 2009-05-27 04:57:51 |         0 | NULL        |
| haha | 2009-05-27 04:57:52 |         0 | NULL        |
| haha | 2009-05-27 04:57:52 |         0 | NULL        |
| haha | 2009-05-27 04:57:53 |         0 | NULL        |
+------+---------------------+-----------+-------------+
4 rows in set (0.00 sec)

Für diejenigen, die nicht denken, den Code ist selbsterklärend:

Warum gibt die Funktion NULL?

War es hilfreich?

Lösung

Benennen Sie Ihre Variablen und den Eingangsparameter, sie sind nicht eindeutig.

Diese Abfrage:

SELECT  body, created, anonymous, screen_name
FROM    idiscussion
LEFT JOIN
        users
ON      idiscussion.uid = users.id
WHERE   idiscussion.iask_id = iask_id

liefert Ihre zuvor deklarierten Variablen (die NULL sind), nicht die Tabellenspalten.

stellen Sie vor den Variablennamen und den Eingangsparameter Namen mit einem Unterstrich.

Auch stellen Sie eine zusätzliche Zuordnung zu führen:

FETCH cur1 INTO body, created, anonymous, screen_name;
SET result = CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>');

Der Handler setzt done nach dem FETCH versagt, aber die result wird dennoch zugeordnet.

Ändern Sie Ihre Handler:

DECLARE EXIT HANDLER FOR SQLSTATE '02000' RETURN result;

Schließlich: in MySQL, kann dies mit einer einzigen Abfrage durchgeführt werden. Es gibt keine Notwendigkeit, es mit einer Funktion zu tun.

SELECT  GROUP_CONCAT(CONCAT(result,'<comment><body><![CDATA[',body,']]></body>','<replier>',if(screen_name is not null and !anonymous,screen_name,''),'</replier>','<created>',created,'</created></comment>') SEPARATOR '')
FROM   idiscussion
LEFT JOIN
       users
ON     idiscussion.uid=users.id
WHERE  idiscussion.iask_id = @_iask_id

Andere Tipps

Beachten Sie, dass mit einem NULL beliebigem Zeichenfolge zusammen verketten NULL zurückzugibt. Versuchen Sie diesen Test:

mysql> SET @s = 'test string';
mysql> SET @s = CONCAT(@s, '<tag>', NULL, '</tag>');
mysql> SELECT @s;

Dies wird NULL zurückgegeben.

So wie Sie eine Schleife durch die Cursor, wenn die body oder created Spalten auf jeder Zeile NULL sind, wird die result NULL. Dann auf nachfolgenden Iterationen der Schleife etwas mit einem NULL result verketteten hat keine Auswirkung; es bleibt NULL.

Versuchen Sie etwas wie folgt aus:

REPEAT
    FETCH cur1 INTO body, created, anonymous, screen_name;
    SET result = CONCAT(result, 
      '<comment><body><![CDATA[', 
      COALESCE(body, ''),
      ']]></body>', 
      '<replier>', 
      IF(COALESCE(anonymous, 0) != 0, COALESCE(screen_name, ''), ''), 
      '</replier>',
      '<created>',
      COALESCE(created, ''),
      '</created></comment>'
    );
UNTIL done END REPEAT;

Die COALESCE() Funktion ist eine nützliche Funktion in Standard-SQL. Es gibt sein erstes Nicht-NULL-Argument.

CONCAT_WS (Separator, STR1, STR2, ...) CONCAT_WS () steht für CONCAT mit Separator und ist eine spezielle Form von CONCAT (). Das erste Argument ist der Separator für den Rest der Argumente. Der Separator wird zwischen den Saiten hinzugefügt verkettet werden: Der Separator den Rest der Argumente eine Zeichenfolge wie möglich sein kann. Wenn das Trennzeichen NULL ist, ist das Ergebnis NULL. Die Funktion überspringt alle NULL-Werte nach dem Trenn Argumente.

mysql>

SELECT CONCAT_WS(",","First name","Second name","Last Name");
   -> 'First name,Second name,Last Name'

mysql>

SELECT CONCAT_WS(",","First name",NULL,"Last Name");
   -> 'First name,Last Name'

Vor MySQL 4.0.14, CONCAT_WS () überspringt leere Strings sowie NULL-Werte.

Ich versuche ausführliche zu sein, weil Ihre Frage ist nicht;)

Sie erwarten, ist der Rückgabewert der Funktion nicht-NULL zu sein, da Sie den Rückgabewert sind die Schaffung von nur nicht-NULL-Zeichenfolgen verketten.

Nur wenn eine der Saiten war NULL, der ganze Rückgabewert wäre NULL. Ihre Demo-Daten enthält nur NULL-Werte in screen_name, aber man respektiert diesen Fall an.

Aber irgendwie (atm ich habe keine Ahnung wie) einer der Werte NULL sein muss und die entsprechende Zeile mit dem großen CONCAT an ist das eine suchen.

Was passiert, wenn Sie die entsprechende Zeile für Debug-Gründe verkürzen:

SET result = if(screen_name is not null,screen_name,'')

Ist es immer noch NULL zurück?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top