【问题标题】:How can I simulate an array variable in MySQL?如何在 MySQL 中模拟数组变量?
【发布时间】:2012-08-23 23:47:04
【问题描述】:

appears MySQL 没有数组变量。我应该改用什么?


似乎有两种选择:set-type scalar临时表。我链接到的问题暗示了前者。但是使用这些而不是数组变量是一种好习惯吗?或者,如果我使用集合,那么基于集合的成语相当于foreach 是什么?

【问题讨论】:

    标签: mysql arrays variables set temp-tables


    【解决方案1】:

    嗯,我一直在使用临时表而不是数组变量。不是最好的解决方案,但它确实有效。

    请注意,您不需要正式定义它们的字段,只需使用 SELECT 创建它们:

    DROP TEMPORARY TABLE IF EXISTS my_temp_table;
    CREATE TEMPORARY TABLE my_temp_table
        SELECT first_name FROM people WHERE last_name = 'Smith';
    

    (另见Create temporary table from select statement without using Create Table。)

    【讨论】:

    • Ohhh :o 我不知道 SQL 有这个!这些表仅在所有正在运行的查询范围内有效。整洁!
    • @Yasky,前提是您不重用连接。因为它确实会持续整个会话。
    • @John:是的,你可以重复使用它,但不能在同一个查询中。
    • 如果你正在重用连接,你通常应该 DROP TEMPORARY TABLE IF EXISTS my_temp_table;在创建它之前。
    【解决方案2】:

    您可以在 MySQL 中使用 WHILE 循环实现此目的:

    SET @myArrayOfValue = '2,5,2,23,6,';
    
    WHILE (LOCATE(',', @myArrayOfValue) > 0)
    DO
        SET @value = ELT(1, @myArrayOfValue);
        SET @myArrayOfValue= SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);
    
        INSERT INTO `EXEMPLE` VALUES(@value, 'hello');
    END WHILE;
    

    编辑: 或者,您可以使用UNION ALL

    INSERT INTO `EXEMPLE`
    (
     `value`, `message`
    )
    (
     SELECT 2 AS `value`, 'hello' AS `message`
     UNION ALL
     SELECT 5 AS `value`, 'hello' AS `message`
     UNION ALL
     SELECT 2 AS `value`, 'hello' AS `message`
     UNION ALL
     ...
    );
    

    【讨论】:

    • 循环不是只能在存储过程中使用吗?
    • 是的,它可能在存储过程、函数和触发器中。
    • 所以我不能使用你提供的代码......我需要一些更普遍适用的东西。
    • 您可以编写一个示例存储过程并CALL它。
    • 我认为不需要数组。您可以使用临时表或UNION ALL 轻松完成此操作,而无需使用过程。
    【解决方案3】:

    尝试使用 MySql 的 FIND_IN_SET() 函数 例如

    SET @c = 'xxx,yyy,zzz';
    
    SELECT * from countries 
    WHERE FIND_IN_SET(countryname,@c);
    

    注意:如果您使用 CSV 值传递参数,则不必在 StoredProcedure 中设置变量。

    【讨论】:

    【解决方案4】:

    现在使用 JSON 数组 将是一个显而易见的答案。

    由于这是一个古老但仍然相关的问题,我制作了一个简短的示例。 JSON 函数自 mySQL 5.7.x / MariaDB 10.2.3 起可用

    我更喜欢这个解决方案而不是 ELT(),因为它真的更像一个数组,而且这个“数组”可以在代码中重复使用。

    但要小心:它 (JSON) 肯定比使用临时表慢得多。它只是更方便。海事组织。

    以下是如何使用 JSON 数组:

    SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                    "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                    "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                    "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';
    
    SELECT JSON_LENGTH(@myjson);
    -- result: 19
    
    SELECT JSON_VALUE(@myjson, '$[0]');
    -- result: gmail.com
    

    这里有一个小例子来展示它是如何在函数/过程中工作的:

    DELIMITER //
    CREATE OR REPLACE FUNCTION example() RETURNS varchar(1000) DETERMINISTIC
    BEGIN
      DECLARE _result varchar(1000) DEFAULT '';
      DECLARE _counter INT DEFAULT 0;
      DECLARE _value varchar(50);
    
      SET @myjson = '["gmail.com","mail.ru","arcor.de","gmx.de","t-online.de",
                    "web.de","googlemail.com","freenet.de","yahoo.de","gmx.net",
                    "me.com","bluewin.ch","hotmail.com","hotmail.de","live.de",
                    "icloud.com","hotmail.co.uk","yahoo.co.jp","yandex.ru"]';
    
      WHILE _counter < JSON_LENGTH(@myjson) DO
        -- do whatever, e.g. add-up strings...
        SET _result = CONCAT(_result, _counter, '-', JSON_VALUE(@myjson, CONCAT('$[',_counter,']')), '#');
    
        SET _counter = _counter + 1;
      END WHILE;
    
      RETURN _result;
    END //
    DELIMITER ;
    
    SELECT example();
    

    【讨论】:

    • 你是说 ELT 慢还是 JSON 慢?
    • @Kanagavelu Sugumar:在撰写本文时,JSON 肯定更慢。我编辑了答案以使其更清楚。
    【解决方案5】:

    不知道数组,但是有一种方法可以将逗号分隔的列表存储在普通的 VARCHAR 列中。

    当您需要在该列表中查找内容时,您可以使用FIND_IN_SET() 函数。

    【讨论】:

    • 如果我想在集合中找到子集,有什么办法吗?
    • 对不起!我不确定这是否可能。
    • 你有最好的解决方案
    【解决方案6】:
    DELIMITER $$
    CREATE DEFINER=`mysqldb`@`%` PROCEDURE `abc`()
    BEGIN
      BEGIN 
        set @value :='11,2,3,1,'; 
        WHILE (LOCATE(',', @value) > 0) DO
          SET @V_DESIGNATION = SUBSTRING(@value,1, LOCATE(',',@value)-1); 
          SET @value = SUBSTRING(@value, LOCATE(',',@value) + 1); 
          select @V_DESIGNATION;
        END WHILE;
      END;
    END$$
    DELIMITER ;
    

    【讨论】:

    • 请解释如何使用此代码以及它如何回答问题。
    • 甲骨文?这个问题与 Oracle 无关。此外,您似乎在过程中定义了一个数组。
    • 请检查 Syntex 是否仅适用于 mysql
    • 不要错过最后一个逗号!
    【解决方案7】:

    我知道这有点晚了,但我最近不得不解决一个类似的问题,并认为这可能对其他人有用。

    背景

    考虑下面名为“mytable”的表格:

    问题是只保留最新的 3 条记录并删除 systemid=1 的任何旧记录(表中可能有许多其他记录具有其他 systemid 值)

    如果您可以简单地使用语句来做到这一点,那就太好了

    DELETE FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)
    

    但是 MySQL 尚不支持此功能,如果您尝试此操作,则会收到类似

    的错误
    ...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'
    

    因此需要一种解决方法,即使用变量将值数组传递给 IN 选择器。但是,由于变量需要是单个值,我需要模拟一个数组诀窍是将数组创建为逗号分隔的值列表(字符串)并将其分配给变量,如下所示

    SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
    

    @myvar 中存储的结果是

    5,6,7

    接下来,使用 FIND_IN_SET 选择器从模拟数组中选择

    SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);
    

    综合最终结果如下:

    SET @myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
    DELETE FROM mytable WHERE FIND_IN_SET(id,@myvar);
    

    我知道这是一个非常具体的案例。但是,可以对其进行修改以适应变量需要存储值数组的任何其他情况。

    我希望这会有所帮助。

    【讨论】:

      【解决方案8】:

      如果您想要关联数组,可以创建一个包含列(键、值)的临时内存表。拥有一个内存表是最接近在 mysql 中拥有数组的东西

      【讨论】:

      • 嗯,我不想要关联数组,只想要数组。
      • 您可以使用只有一列的临时内存表,然后使用游标遍历值,这是最接近在非声明性编程语言中使用数组和 for/while 循环的方法跨度>
      • 该语言实际上有这个特性,也就是说,没有语法上的理由你不应该像选择一个标量一样选择一个向量到一个变量中。
      【解决方案9】:

      我是这样做的。

      首先,我创建了一个函数,用于检查 Long/Integer/whatever 值是否在以逗号分隔的值列表中:

      CREATE DEFINER = 'root'@'localhost' FUNCTION `is_id_in_ids`(
              `strIDs` VARCHAR(255),
              `_id` BIGINT
          )
          RETURNS BIT(1)
          NOT DETERMINISTIC
          CONTAINS SQL
          SQL SECURITY DEFINER
          COMMENT ''
      BEGIN
      
        DECLARE strLen    INT DEFAULT 0;
        DECLARE subStrLen INT DEFAULT 0;
        DECLARE subs      VARCHAR(255);
      
        IF strIDs IS NULL THEN
          SET strIDs = '';
        END IF;
      
        do_this:
          LOOP
            SET strLen = LENGTH(strIDs);
            SET subs = SUBSTRING_INDEX(strIDs, ',', 1);
      
            if ( CAST(subs AS UNSIGNED) = _id ) THEN
              -- founded
              return(1);
            END IF;
      
            SET subStrLen = LENGTH(SUBSTRING_INDEX(strIDs, ',', 1));
            SET strIDs = MID(strIDs, subStrLen+2, strLen);
      
            IF strIDs = NULL or trim(strIds) = '' THEN
              LEAVE do_this;
            END IF;
      
        END LOOP do_this;
      
         -- not founded
        return(0);
      
      END;
      

      所以现在您可以在以逗号分隔的 ID 列表中搜索 ID,如下所示:

      select `is_id_in_ids`('1001,1002,1003',1002);
      

      您可以在 WHERE 子句中使用此函数,如下所示:

      SELECT * FROM table1 WHERE `is_id_in_ids`('1001,1002,1003',table1_id);
      

      这是我发现将“数组”参数传递给 PROCEDURE 的唯一方法。

      【讨论】:

        【解决方案10】:

        我很惊讶没有一个答案提到 ELT/FIELD。

        ELT/FIELD 的工作方式与数组非常相似,尤其是在您有静态数据的情况下。

        FIND_IN_SET 也有类似的作用,但没有内置的补充 函数,但写一个很容易。

        mysql> select elt(2,'AA','BB','CC');
        +-----------------------+
        | elt(2,'AA','BB','CC') |
        +-----------------------+
        | BB                    |
        +-----------------------+
        1 row in set (0.00 sec)
        
        mysql> select field('BB','AA','BB','CC');
        +----------------------------+
        | field('BB','AA','BB','CC') |
        +----------------------------+
        |                          2 |
        +----------------------------+
        1 row in set (0.00 sec)
        
        mysql> select find_in_set('BB','AA,BB,CC');
        +------------------------------+
        | find_in_set('BB','AA,BB,CC') |
        +------------------------------+
        |                            2 |
        +------------------------------+
        1 row in set (0.00 sec)
        
        mysql>  SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1);
        +-----------------------------------------------------------+
        | SUBSTRING_INDEX(SUBSTRING_INDEX('AA,BB,CC',',',2),',',-1) |
        +-----------------------------------------------------------+
        | BB                                                        |
        +-----------------------------------------------------------+
        1 row in set (0.01 sec)
        

        【讨论】:

          【解决方案11】:

          这适用于值列表:

          SET @myArrayOfValue = '2,5,2,23,6,';
          
          WHILE (LOCATE(',', @myArrayOfValue) > 0)
          DO
          SET @value = ELT(1, @myArrayOfValue);
              SET @STR = SUBSTRING(@myArrayOfValue, 1, LOCATE(',',@myArrayOfValue)-1);
              SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',', @myArrayOfValue) + 1);
          
              INSERT INTO `Demo` VALUES(@STR, 'hello');
          END WHILE;
          

          【讨论】:

            【解决方案12】:

            数组变量真的有必要吗?

            我之所以问是因为我最初来到这里是想添加一个数组作为 MySQL 表变量。我对数据库设计比较陌生,并试图思考如何以典型的编程语言方式来做。

            但数据库不同。我以为我想要一个数组作为变量,但事实证明这不是常见的 MySQL 数据库实践。

            标准做法

            数组的替代解决方案是添加一个额外的表,然后使用外键引用您的原始表。

            举个例子,让我们想象一个应用程序,它跟踪一个家庭中每个人都想在商店购买的所有物品。

            我最初设想的用于创建表的命令看起来像这样:

            #doesn't work
            CREATE TABLE Person(
              name VARCHAR(50) PRIMARY KEY
              buy_list ARRAY
            );
            

            我想我将 buy_list 设想为以逗号分隔的项目字符串或类似的东西。

            但是 MySQL 没有数组类型字段,所以我真的需要这样的东西:

            CREATE TABLE Person(
              name VARCHAR(50) PRIMARY KEY
            );
            CREATE TABLE BuyList(
              person VARCHAR(50),
              item VARCHAR(50),
              PRIMARY KEY (person, item),
              CONSTRAINT fk_person FOREIGN KEY (person) REFERENCES Person(name)
            );
            

            这里我们定义了一个名为 fk_person 的约束。它说 BuyList 中的“人”字段是外键。换句话说,它是另一个表中的主键,特别是 Person 表中的“名称”字段,即 REFERENCES 表示的。

            我们还定义了 person 和 item 的组合作为主键,但从技术上讲,这不是必需的。

            最后,如果你想得到一个人列表中的所有项目,你可以运行这个查询:

            SELECT item FROM BuyList WHERE person='John';
            

            这将为您提供 John 列表中的所有项目。不需要数组!

            【讨论】:

            • 我接受的解决方案使用临时表。
            • 当然。然后,我为像我这样进入此页面寻找创建数组类型的方法的任何人提供了这个答案——他们最初并不理解为什么数组不是 MySQL 中的一种类型。它似乎是设计使然。一般情况没有在这里表示,所以我将我学到的内容包括在内,以便其他人了解通常不需要数组。我不希望你选择我的答案。这取决于用例。您已经接受了针对特定用例的答案,而我正在为一般用例提供此答案。
            【解决方案13】:

            这是我使用包含元素列表的变量的解决方案。 您可以在简单查询中使用它(无需使用存储过程或创建表)。

            我在网站的其他地方发现了使用 JSON_TABLE 函数的技巧(它适用于 mysql 8,我不知道它适用于其他版本)。

            set @x = '1,2,3,4' ;
            
            select c.NAME
            from colors c
            where 
              c.COD in ( 
                select * 
                from json_table( 
                  concat('[',@x,']'),
                  '$[*]' columns (id int path '$') ) t ) ;
            

            此外,您可能需要管理一个或多个变量设置为 empty_string 的情况。 在这种情况下,我添加了另一个技巧(即使 xyx 和 y 都是空字符串,查询也不会返回错误) :

            set @x = '' ;
            set @y = 'yellow' ;
            
            select c.NAME
            from colors 
            where 
              if(@y = '', 1 = 1, c.NAME = @y)
              and if(@x = '', 1, c.COD) in ( 
                select * 
                from json_table(
                  concat('[',if(@x = '', 1, @x),']'),
                  '$[*]' columns (id int path '$') ) t) ;
            

            【讨论】:

              【解决方案14】:

              使用集合的两个版本都不适合我(用 MySQL 5.5 测试)。函数 ELT() 返回整个集合。考虑到 WHILE 语句仅在 PROCEDURE 上下文中可用,我将其添加到我的解决方案中:

              DROP PROCEDURE IF EXISTS __main__;
              
              DELIMITER $
              CREATE PROCEDURE __main__()
              BEGIN
                  SET @myArrayOfValue = '2,5,2,23,6,';
              
                  WHILE (LOCATE(',', @myArrayOfValue) > 0)
                  DO
                      SET @value = LEFT(@myArrayOfValue, LOCATE(',',@myArrayOfValue) - 1);    
                      SET @myArrayOfValue = SUBSTRING(@myArrayOfValue, LOCATE(',',@myArrayOfValue) + 1);
                  END WHILE;
              END;
              $
              DELIMITER ;
              
              CALL __main__;
              

              说实话,我认为这不是一个好习惯。即使它真的有必要,这也很难读,而且速度很慢。

              【讨论】:

                【解决方案15】:

                数组不是要高效吗?如果您只是遍历值,我认为临时(或永久)表上的游标比寻找逗号更有意义,不是吗?也更干净。查找“mysql DECLARE CURSOR”。

                用于随机访问具有数字索引主键的临时表。不幸的是,您将获得的最快访问是哈希表,而不是真正的随机访问。

                【讨论】:

                • 这是评论,不是答案。我没有表明这是我想要对数组执行的操作。
                【解决方案16】:

                查看相同问题的另一种方式。 希望有帮助

                DELIMITER $$
                CREATE PROCEDURE ARR(v_value VARCHAR(100))
                BEGIN
                
                DECLARE v_tam VARCHAR(100);
                DECLARE v_pos VARCHAR(100);
                
                CREATE TEMPORARY TABLE IF NOT EXISTS split (split VARCHAR(50));
                
                SET v_tam = (SELECT (LENGTH(v_value) - LENGTH(REPLACE(v_value,',',''))));
                SET v_pos = 1;
                
                WHILE (v_tam >= v_pos)
                DO
                    INSERT INTO split 
                    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(v_value,',',v_pos),',', -1);
                    SET v_pos = v_pos + 1;
                END WHILE;
                
                SELECT * FROM split;
                
                DROP TEMPORARY TABLE split;
                
                END$$
                
                
                CALL ARR('1006212,1006404,1003404,1006505,444,');
                

                【讨论】:

                • 其实你在这里说的不是很清楚。 7年前的这个问题有几个相关的答案。考虑删除您的答案或直接/一般地解释您试图告诉我们的内容,而不是通过示例。
                【解决方案17】:

                如果我们有一张这样的桌子

                mysql> select * from user_mail;
                +------------+-------+
                | email      | user | 
                +------------+-------+-
                | email1@gmail |     1 | 
                | email2@gmail |     2 |
                +------------+-------+--------+------------+
                

                还有数组表:

                mysql> select * from user_mail_array;
                +------------+-------+-------------+
                | email      | user | preferences |
                +------------+-------+-------------+
                | email1@gmail |     1 |           1 |
                | email1@gmail |     1 |           2 |
                | email1@gmail |     1 |           3 |
                | email1@gmail |     1 |           4 |
                | email2@gmail |     2 |           5 |
                | email2@gmail |     2 |           6 |
                

                我们可以通过CONCAT函数将第二个表的行选择为一个数组:

                mysql> SELECT t1.*, GROUP_CONCAT(t2.preferences) AS preferences
                     FROM user_mail t1,user_mail_array t2
                       where t1.email=t2.email and t1.user=t2.user
                     GROUP BY t1.email,t1.user;
                
                +------------+-------+--------+------------+-------------+
                | email      | user | preferences |
                +------------+-------+--------+------------+-------------+
                |email1@gmail |     1 | 1,3,2,4     |
                |email2@gmail |     2 | 5,6         |
                +------------+-------+--------+------------+-------------+
                

                【讨论】:

                • 我认为是克林顿回答的副本。
                【解决方案18】:

                在 MYSQL 5.7.x 之后的版本中,可以使用 JSON 类型来存储数组。您可以通过 MYSQL 通过键获取数组的值。

                【讨论】:

                • 你能举个例子说明我会怎么做吗?
                【解决方案19】:

                受函数ELT(index number, string1, string2, string3,…)的启发,我认为下面的例子是一个数组例子:

                set @i := 1;
                while @i <= 3
                do
                  insert into table(val) values (ELT(@i ,'val1','val2','val3'...));
                set @i = @i + 1;
                end while;
                

                希望对您有所帮助。

                【讨论】:

                  【解决方案20】:

                  这是一个 MySQL 循环逗号分隔字符串的示例。

                  DECLARE v_delimited_string_access_index INT;
                  DECLARE v_delimited_string_access_value VARCHAR(255);
                  DECLARE v_can_still_find_values_in_delimited_string BOOLEAN;
                  
                  SET v_can_still_find_values_in_delimited_string = true;
                  SET v_delimited_string_access_index = 0;
                  WHILE (v_can_still_find_values_in_delimited_string) DO
                    SET v_delimited_string_access_value = get_from_delimiter_split_string(in_array, ',', v_delimited_string_access_index); -- get value from string
                    SET v_delimited_string_access_index = v_delimited_string_access_index + 1;
                    IF (v_delimited_string_access_value = '') THEN
                      SET v_can_still_find_values_in_delimited_string = false; -- no value at this index, stop looping
                    ELSE
                      -- DO WHAT YOU WANT WITH v_delimited_string_access_value HERE
                    END IF;
                  END WHILE;
                  

                  这使用了这里定义的get_from_delimiter_split_string 函数:https://stackoverflow.com/a/59666211/3068233

                  【讨论】:

                  • 多年前已经建议使用逗号分隔的字符串。
                  • @einpoklum 是的 - 这是与他们互动的另一种方式
                  【解决方案21】:

                  我认为我可以改进这个答案。试试这个:

                  参数“Pranks”是一个 CSV。 IE。 '1,2,3,4......等等'

                  CREATE PROCEDURE AddRanks(
                  IN Pranks TEXT
                  )
                  BEGIN
                    DECLARE VCounter INTEGER;
                    DECLARE VStringToAdd VARCHAR(50);
                    SET VCounter = 0;
                    START TRANSACTION;
                    REPEAT
                      SET VStringToAdd = (SELECT TRIM(SUBSTRING_INDEX(Pranks, ',', 1)));
                      SET Pranks = (SELECT RIGHT(Pranks, TRIM(LENGTH(Pranks) - LENGTH(SUBSTRING_INDEX(Pranks, ',', 1))-1)));
                      INSERT INTO tbl_rank_names(rank)
                      VALUES(VStringToAdd);
                      SET VCounter = VCounter + 1;
                    UNTIL (Pranks = '')
                    END REPEAT;
                    SELECT VCounter AS 'Records added';
                    COMMIT;
                  END;
                  

                  这种方法使搜索到的 CSV 值字符串随着循环的每次迭代而逐渐变短,我相信这对优化会更好。

                  【讨论】:

                  • 你指的“这个答案”是什么?此外,您没有 CSV 文件。
                  • 我指的不是 CSV 文件,我指的是 CSV 值,例如“1,2,3,4...等”
                  【解决方案22】:

                  我会为多个集合尝试这样的事情。我是 MySQL 初学者。很抱歉函数名称,无法确定最好的名称。

                  delimiter //
                  
                  drop  procedure init_
                  //
                  create procedure init_()
                  begin
                    CREATE TEMPORARY TABLE if not exists 
                      val_store(  
                      realm  varchar(30) 
                      ,  id  varchar(30) 
                      ,  val   varchar(255) 
                      ,  primary key ( realm , id )
                      );
                  end;
                  //
                  
                  drop function if exists get_
                  //
                  create function get_( p_realm varchar(30) , p_id varchar(30) )
                    returns varchar(255)
                    reads sql data
                  begin 
                    declare ret_val varchar(255);
                    declare continue handler for 1146 set ret_val = null;
                    select val into ret_val from val_store where id = p_id;
                    return ret_val;
                  end;
                  //
                  
                  drop procedure if exists set_
                  //
                  create procedure set_( p_realm varchar(30) , p_id varchar(30) , p_val varchar(255) )
                  begin
                    call init_(); 
                    insert into val_store (realm,id,val) values (p_realm , p_id , p_val) on duplicate key update val = p_val;
                  end;
                  //
                  
                  drop   procedure if exists remove_
                  //
                  create procedure remove_( p_realm varchar(30) , p_id varchar(30) )
                  begin
                    call init_();
                    delete from val_store where realm = p_realm and id = p_id;
                  end;
                  //
                  
                  drop   procedure if exists erase_
                  //
                  create procedure erase_( p_realm varchar(30) ) 
                  begin
                    call init_();
                    delete from val_store where realm = p_realm;
                  end;
                  //
                  
                  call set_('my_array_table_name','my_key','my_value');
                  
                  select get_('my_array_table_name','my_key');
                  

                  【讨论】:

                  • 我想我明白你的建议,但这很笨拙,而且可能也非常慢......
                  • 如果不对它进行压力测试,我无法支持或拒绝它。它基本上是临时表(或普通表)上的主键查找和插入。我会一直使用它,直到遇到问题或找到更好的方法;但我会做一些奇怪的事情,比如完全用 Oracle PL/SQL 编写编译器和游戏。
                  【解决方案23】:

                  而不是将数据保存为数组或仅保存在一行中,您应该为收到的每个值创建不同的行。这将使它更容易理解,而不是放在一起。

                  【讨论】:

                  • 请分享如何做到这一点
                  【解决方案24】:

                  您是否尝试过使用 PHP 的 serialize()? 这允许您将变量数组的内容存储在 PHP 可以理解且对数据库安全的字符串中(假设您已先对其进行转义)。

                  $array = array(
                      1 => 'some data',
                      2 => 'some more'
                  );
                  
                  //Assuming you're already connected to the database
                  $sql = sprintf("INSERT INTO `yourTable` (`rowID`, `rowContent`) VALUES (NULL, '%s')"
                       ,  serialize(mysql_real_escape_string($array, $dbConnection)));
                  mysql_query($sql, $dbConnection) or die(mysql_error());
                  

                  你也可以在没有编号的数组的情况下做同样的事情

                  $array2 = array(
                      'something' => 'something else'
                  );
                  

                  $array3 = array(
                      'somethingNew'
                  );
                  

                  【讨论】:

                  • 我没有使用 PHP,所以这对我来说并不重要。
                  • 使用 JSON 而不是序列化。它更通用且独立于语言。
                  猜你喜欢
                  • 2021-12-08
                  • 2021-10-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-11-20
                  • 2020-10-09
                  • 2016-04-26
                  相关资源
                  最近更新 更多