Comment utiliser les valeurs renvoyées de la fonction de MySQL stockées avec fonction ()?

StackOverflow https://stackoverflow.com/questions/8341477

  •  26-10-2019
  •  | 
  •  

Question

J'ai un champ nommé 'dealBusinessLocations' (dans une table '' dp_deals) qui contiennent des ids d'une autre table (dp_business_locations) en format séparé par des virgules.

dealBusinessLocations
----------------------
0,20,21,22,23,24,25,26

Je dois utiliser ces valeurs dans un en () fonction d'une requête.

comme

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (d.dealBusinessLocations) ;

Sine MySQL ne supporte pas une chaîne fonction exploser, j'ai créé une fonction stockée

delimiter //
DROP FUNCTION IF EXISTS BusinessList;
create function BusinessList(BusinessIds text) returns text deterministic
BEGIN
  declare i int default 0;
  declare TmpBid text;
  declare result text default '';
  set TmpBid = BusinessIds;
  WHILE LENGTH(TmpBid) > 0 DO
           SET i = LOCATE(',', TmpBid);
           IF (i = 0)
                   THEN SET i = LENGTH(TmpBid) + 1;
           END IF;
           set result =  CONCAT(result,CONCAT('\'',SUBSTRING(TmpBid, 1, i - 1),'\'\,'));
           SET TmpBid =  SUBSTRING(TmpBid, i + 1, LENGTH(TmpBid));
  END WHILE;
  IF(LENGTH(result) > 0)
      THEN SET result = SUBSTRING(result,1,LENGTH(result)-1);
  END IF;
  return result;
END// 
delimiter  ;

La fonction fonctionne parfaitement.

mysql> BusinessList( '21,22' )
BusinessList( '21,22' )
-----------------------
'21','22'

Mais la requête en utilisant la fonction n'a pas fonctionné non plus. voici la requête.

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (BusinessList(d.dealBusinessLocations)));

J'ai aussi essayé d'utiliser la valeur statique pour la fonction argumet, mais aucune utilisation

select * from dp_deals as d left join dp_business_locations as b on(b.businessLocID IN (BusinessList('21,22')));

Il semble qu'il y ait un problème avec l'utilisation de la valeur renvoyée par la fonction.

Était-ce utile?

La solution

Tout d'abord, lisez ceci:

Is storing a comma separated list in a database column really that bad?
Yes, it is

Alors, allez normaliser vos tables.


Maintenant, si vous ne pouvez vraiment pas faire autrement, ou jusqu'à ce que vous Normaliser, utilisez le FIND_IN_SET() fonction :

select * 
from dp_deals as d 
  left join dp_business_locations as b 
    on FIND_IN_SET(b.businessLocID, d.dealBusinessLocations)

Alors, relisez cet article. Si la requête est lente ou si vous avez d'autres problèmes avec ce tableau, vous saurez pourquoi:

Is storing a comma separated list in a database column really that bad?
Yes, it is

Autres conseils

Simple, utilisez find_in_set() à la place.

SELECT * 
FROM dp_deals as d 
LEFT JOIN dp_business_locations as b 
       ON (FIND_IN_SET(b.businessLocID,d.dealBusinessLocations) > 0); 

Voir: http: // dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set

Notez que si vous déposez CSV et de sortir de l'enfer, vous pouvez utiliser un simple rejoindre comme:

SELECT d.*, GROUP_CONCAT(b.dealBusinessLocation) as locations
FROM dp_deals as d 
LEFT JOIN dp_business_location as b 
       ON (d.dealBusinessLocation = b.businessLocID); 

Ce qui sera beaucoup plus rapide et normalisé comme un bonus.

Je pense que votre problème est que IN() ne vous attendez pas à obtenir une chaîne avec beaucoup de champs, mais beaucoup de champs.

Avec votre fonction que vous l'envoyez ceci:

WHERE something IN ('\'21\',\'22\''); /* i.e. a single text containing "'21','22'" */

Et pas attendu

WHERE something IN ('21','22');
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top