【问题标题】:How to cycle with an array in MySQL?如何在 MySQL 中循环使用数组?
【发布时间】:2012-02-09 16:57:20
【问题描述】:

我想创建一个存储过程或一个普通查询,其值通过数组传递。

例子:

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;

显然这是行不通的,但我想知道如何实现这一点。

【问题讨论】:

    标签: mysql arrays stored-procedures while-loop


    【解决方案1】:

    现有的答案都不适合我,所以我最终实现了我自己的(也是第一个)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
    

    【讨论】:

    • Devart 的回答对于这个例子来说非常有效。就我而言,我希望添加帐户、用户名、密码和相同的权限集。 Neurotransmitter 的解决方案非常适合这种情况。
    • 这可以使tablex作为元素的变量吗?当我尝试做同样的事情时,mysql 认为它是一个表并说表 schema.element 不存在。如何将变量作为表做同样的事情,而 var 将包含所有表的定义?
    【解决方案2】:

    如果您可以创建一个表来存储数组值,则无需编写循环即可。使用 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;
    

    【讨论】:

      【解决方案3】:

      试试这样的:

      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;
      

      【讨论】:

        【解决方案4】:

        我猜你只是想:

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

        您对如何将数组传递给过程有疑问吗?

        【讨论】:

        • 问题是我需要为每个数组条目循环。
        【解决方案5】:

        尝试在没有存储例程的情况下执行此操作 -

        SET @arr = 'hi,hello,good'; -- your array
        
        SELECT COUNT(*) FROM tablex
          WHERE FIND_IN_SET (name, @arr); -- calculate count
        

        【讨论】:

          【解决方案6】:

          关系数据库不处理数组,它们处理标量、行和表。 SQL 在很大程度上是一种声明性语言,而不是过程性语言。

          要对表中的条目进行计数,请使用 COUNT 聚合函数:

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

          如果您需要在单个语句中处理可变数量的值来匹配,您可以创建一个临时表来保存这些值,而不是使用IN

          SELECT COUNT(*)
            FROM tablex
            JOIN names ON tablex.name=names.name
          

          【讨论】:

          • 这不是我想要的。我不需要计算表中的条目,而是为每个数组条目循环选择语句。
          • @Davide:“循环选择语句”是什么意思?请通过包括示例表架构(作为CREATE TABLE 语句)、数据(作为INSERT ... INTO 语句)和所需结果来完成您问题中的example
          • 在编程语言中
            x = new Array("a", "b", "c");
          • @Davide:你的意思是“循环”吗?循环不是您所需要的,这只是您的solution 对于您尚未描述的其他问题。编辑您的问题并解释您really need 的内容。 SQL 并不是真正的编程语言,它是一种声明性数据语言。它有程序元素,但这些都是附加的,不应该是主要的表达方式。
          【解决方案7】:

          存储过程中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 ;
          

          您可以查看this article 以获取数组示例。

          【讨论】:

            猜你喜欢
            • 2017-07-25
            • 2014-06-23
            • 2017-06-02
            • 1970-01-01
            • 2020-08-29
            • 1970-01-01
            • 2020-08-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多