Je dois passer un tableau de chaînes en tant que paramètre à une routine stockée MySQL. Le tableau peut être long et son nombre d'éléments n'est pas fixe. Je souhaite ensuite placer les valeurs de chaîne dans une table en mémoire avec une colonne afin de pouvoir utiliser les données. Je ne sais pas si cela peut être fait avec MySQL. Peut-être que des solutions de contournement sont nécessaires.
Par exemple, j'ai les valeurs de chaîne:
Banana, Apple, Orange
Maintenant, je veux obtenir des données sur ces fruits à partir de ma table MySQL Fruits
. Pseudo code:
create function GetFruits(Array fruitArray)
declare @temp table as
fruitName varchar(100)
end
@temp = convert fruitArray to table
select * from Fruits where Name in (select fruitName from @temp)
end
Microsoft SQL Server vous permet d'utiliser le type de données TEXT
et de soumettre le tableau en tant que chaîne XML, en créant rapidement le tableau en mémoire. Cependant, je ne pense pas que cette technique soit possible dans MySQL.
Toute aide sur la façon de le faire serait appréciée!
Vous pouvez passer une chaîne avec votre liste et utiliser un instructions préparées pour exécuter une requête, par exemple. -
DELIMITER $$
CREATE PROCEDURE GetFruits(IN fruitArray VARCHAR(255))
BEGIN
SET @sql = CONCAT('SELECT * FROM Fruits WHERE Name IN (', fruitArray, ')');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
$$
DELIMITER ;
Comment utiliser:
SET @fruitArray = '\'Apple\',\'banana\'';
CALL GetFruits(@fruitArray);
Utilisez simplement FIND_IN_SET comme ça:
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
alors tu peux faire:
select * from Fruits where FIND_IN_SET(fruit, fruitArray) > 0
Cela m’aide à le faire à condition d’espérer que cela vous aidera.
CREATE PROCEDURE `test`(IN Array_String VARCHAR(100))
BEGIN
SELECT * FROM Table_Name
WHERE FIND_IN_SET(field_name_to_search, Array_String);
END//;
Appel:
call test('3,2,1');
Utilisez une jointure avec une table temporaire. Vous n'avez pas besoin de passer des tables temporaires à des fonctions, elles sont globales .
create temporary table ids( id int ) ;
insert into ids values (1),(2),(3) ;
delimiter //
drop procedure if exists tsel //
create procedure tsel() -- uses temporary table named ids. no params
READS SQL DATA
BEGIN
-- use the temporary table `ids` in the SELECT statement or
-- whatever query you have
select * from Users INNER JOIN ids on userId=ids.id ;
END //
DELIMITER ;
CALL tsel() ; -- call the procedure
Si vous ne voulez pas utiliser de tables temporaires, voici une chaîne divisée comme une fonction que vous pouvez utiliser.
SET @Array = 'one,two,three,four';
SET @ArrayIndex = 2;
SELECT CASE
WHEN @Array REGEXP CONCAT('((,).*){',@ArrayIndex,'}')
THEN SUBSTRING_INDEX(SUBSTRING_INDEX(@Array,',',@ArrayIndex+1),',',-1)
ELSE NULL
END AS Result;
SUBSTRING_INDEX(string, delim, n)
renvoie le premier nSUBSTRING_INDEX(string, delim, -1)
renvoie le dernier seulementREGEXP '((delim).*){n}'
vérifie s'il y a n délimiteurs (c'est-à-dire que vous êtes dans les limites)J'ai mis au point une solution peu pratique mais fonctionnelle à mon problème. Cela fonctionne pour un tableau unidimensionnel (plus de dimensions seraient délicates) et une entrée qui rentre dans un varchar
:
declare pos int; -- Keeping track of the next item's position
declare item varchar(100); -- A single item of the input
declare breaker int; -- Safeguard for while loop
-- The string must end with the delimiter
if right(inputString, 1) <> '|' then
set inputString = concat(inputString, '|');
end if;
DROP TABLE IF EXISTS MyTemporaryTable;
CREATE TEMPORARY TABLE MyTemporaryTable ( columnName varchar(100) );
set breaker = 0;
while (breaker < 2000) && (length(inputString) > 1) do
-- Iterate looking for the delimiter, add rows to temporary table.
set breaker = breaker + 1;
set pos = INSTR(inputString, '|');
set item = LEFT(inputString, pos - 1);
set inputString = substring(inputString, pos + 1);
insert into MyTemporaryTable values(item);
end while;
Par exemple, l'entrée pour ce code pourrait être la chaîne Apple|Banana|Orange
. MyTemporaryTable
sera peuplé de trois lignes contenant les chaînes Apple
, Banana
et Orange
respectivement.
Je pensais que la lenteur de la gestion des chaînes rendrait cette approche inutile, mais elle était assez rapide (une fraction de seconde pour un tableau de 1 000 entrées).
J'espère que ça aide quelqu'un.
Ceci simule un tableau de caractères mais vous pouvez remplacer SUBSTR par ELT pour simuler un tableau de chaînes.
declare t_tipos varchar(255) default 'ABCDE';
declare t_actual char(1);
declare t_indice integer default 1;
while t_indice<length(t_tipos)+1 do
set t_actual=SUBSTR(t_tipos,t_indice,1);
select t_actual;
set t_indice=t_indice+1;
end while;