Как зациклить с массивом в MySQL? - PullRequest
5 голосов
/ 13 января 2012

Я хотел бы создать хранимую процедуру или обычный запрос со значениями, переданными в массиве.

Пример:

CREATE PROCEDURE proc() 
BEGIN 
    DECLARE cont INTEGER; 
    DECLARE var ARRAY; 
    SET cont = 0;
    SET var = ("hi", "hello", "good", ...)

    WHILE cont < 12 DO 
        SELECT * FROM tablex
        WHERE name = var[cont];
        SET cont = cont + 1; 
    END WHILE; 
END;

Очевидно, что это не сработает, но я бы хотел знать, как этого добиться.

Ответы [ 7 ]

10 голосов
/ 13 января 2012

Попробуйте сделать это без хранимой рутины -

SET @arr = 'hi,hello,good'; -- your array

SELECT COUNT(*) FROM tablex
  WHERE FIND_IN_SET (name, @arr); -- calculate count
5 голосов
/ 02 августа 2016

Ни один из существующих ответов не работал для меня, поэтому я в итоге реализовал свою собственную процедуру MySQL. Это довольно легко.

PROCEDURE db.loop_through_array()
BEGIN
  DECLARE var varchar(150) DEFAULT 'hi,hello,good';
  DECLARE element varchar(150);

  WHILE var != '' DO
    SET element = SUBSTRING_INDEX(var, ',', 1);      
    SELECT * FROM tablex WHERE name = element;

    IF LOCATE(',', var) > 0 THEN
      SET var = SUBSTRING(var, LOCATE(',', var) + 1);
    ELSE
      SET var = '';
    END IF;
  END WHILE;
END
2 голосов
/ 19 апреля 2013

Попробуйте что-то вроде этого:

CREATE PROCEDURE proc()
BEGIN 
    DECLARE cont INTEGER; 
    SET cont = 0;
    CREATE TEMPORARY TABLE array_table (idx INT, value VARCHAR(20));
    INSERT INTO array_table (idx, value) VALUES (1,"hi"),(2,"hello"),(3,"good"),...;
    WHILE cont < 12 DO 
        SELECT * FROM tablex
        WHERE name IN (SELECT value FROM array_table WHERE idx = cont);
        SET cont = cont + 1; 
    END WHILE; 
END;
2 голосов
/ 13 января 2012

Реляционные базы данных не делают массивов, они делают скаляры, строки и таблицы.SQL в значительной степени является декларативным, а не процедурным языком.

Для подсчета записей в таблице используйте агрегатную функцию COUNT:

SELECT COUNT(*)
  FROM tablex
  WHERE name IN ("hi", "hello", "good", ...)

Если вынеобходимо обработать переменное число значений для сопоставления в одном операторе, вы можете создать временную таблицу для хранения значений вместо использования IN:

SELECT COUNT(*)
  FROM tablex
  JOIN names ON tablex.name=names.name
1 голос
/ 13 января 2012

пример цикла WHILE внутри хранимой процедуры:

DELIMITER $$
DROP PROCEDURE IF EXISTS WhileLoopProc$$
CREATE PROCEDURE WhileLoopProc()
      BEGIN
              DECLARE x  INT;
              DECLARE str  VARCHAR(255);
              SET x = 1;
              SET str =  '';
              WHILE x  <= 5 DO
                          SET  str = CONCAT(str,x,',');
                          SET  x = x + 1; 
              END WHILE;
              SELECT str;
      END$$
DELIMITER ;

вы можете проверить эту статью для примеров массивов.

0 голосов
/ 23 декабря 2017

Если вы можете создать таблицу для хранения значений массива, вы можете сделать это без написания цикла.Используйте оператор in ().

CREATE TABLE test_strings (element CHAR(6));
INSERT INTO  test_strings (element) VALUES ('hi'),('hello'),('good');

SELECT * FROM tablex t
    WHERE name IN(SELECT element FROM test_strings)
    ORDER BY t.name;
0 голосов
/ 13 января 2012

Полагаю, вы просто хотите:

SELECT * FROM tablex
WHERE name IN ('hi', 'hello', 'good', ...)

У вас есть проблема с передачей массива в процедуру?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...