Pasar matriz a la rutina almacenada de MySQL

Necesito pasar una serie de cadenas como parámetro a una rutina almacenada de MySQL. La matriz puede ser larga y su número de elementos no es fijo. Luego quiero poner los valores de cadena en una tabla en memoria con una columna, para que pueda trabajar con los datos. No sé si esto se puede hacer en MySQL. Tal vez se necesitan soluciones sucias.

Por ejemplo, tengo los valores de cadena:

Banana, Apple, Orange 

Ahora quiero obtener datos sobre estas frutas de mi tabla MySQL Fruits . Pseudo código:

 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 le permite usar el tipo de datos TEXT y enviar la matriz como una cadena XML, creando rápidamente la tabla en memoria. Sin embargo, no creo que esa técnica sea posible en MySQL.

¡Cualquier ayuda sobre cómo hacer esto sería apreciada!

Puede pasar una cadena con su lista y usar una statement preparada para ejecutar una consulta, por ejemplo:

 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 ; 

Cómo utilizar:

 SET @fruitArray = '\'apple\',\'banana\''; CALL GetFruits(@fruitArray); 

Simplemente use FIND_IN_SET así:

 mysql> SELECT FIND_IN_SET('b','a,b,c,d'); -> 2 

para que puedas hacer:

 select * from Fruits where FIND_IN_SET(fruit, fruitArray) > 0 

Esto me ayuda a hacerlo EN CONDICIÓN Espero que esto te ayude …

 CREATE PROCEDURE `test`(IN Array_String VARCHAR(100)) BEGIN SELECT * FROM Table_Name WHERE FIND_IN_SET(field_name_to_search, Array_String); END//; 

Vocación:

  call test('3,2,1'); 

Use una combinación con una tabla temporal. No necesita pasar tablas temporales a funciones, son 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 no desea utilizar tablas temporales, aquí hay una función de cadena dividida que puede usar

 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) devuelve la primera n
  • SUBSTRING_INDEX(string, delim, -1) devuelve el último
  • REGEXP '((delim).*){n}' comprueba si hay n delimitadores (es decir, usted está dentro de límites)

He encontrado una solución incómoda pero funcional para mi problema. Funciona para una matriz unidimensional (más dimensiones serían engañosas) y la entrada que cabe en una 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; 

Por ejemplo, la entrada para este código podría ser la cadena Apple|Banana|Orange . MyTemporaryTable se completará con tres filas que contienen las cadenas Apple , Banana y Orange respectivamente.

Pensé que la lentitud de la manipulación de cadenas haría que este enfoque fuera inútil, pero fue lo suficientemente rápido (solo una fracción de segundo para una matriz de 1,000 entradas).

Espero que esto ayude a alguien.

Esto simula una matriz de caracteres pero puede sustituir SUBSTR por ELT para simular una matriz de cadenas

 declare t_tipos varchar(255) default 'ABCDE'; declare t_actual char(1); declare t_indice integer default 1; while t_indice