简体   繁体   English

如何在 MySQL 中模拟数组变量?

[英]How can I simulate an array variable in MySQL?

It appears that MySQL doesn't have array variables. MySQL似乎没有数组变量。 What should I use instead?我应该改用什么?


There seem to be two alternatives suggested: A set-type scalar and temporary tables .似乎有两种选择:一个集合类型的标量临时表 The question I linked to suggests the former.我链接到的问题暗示了前者。 But is it good practice to use these instead of array variables?但是使用这些而不是数组变量是一种好习惯吗? Alternatively, if I go with sets, what would be the set-based idiom equivalent to foreach ?或者,如果我使用集合,那么基于集合的成语相当于foreach是什么?

Well, I've been using temporary tables instead of array variables.好吧,我一直在使用临时表而不是数组变量。 Not the greatest solution, but it works.不是最好的解决方案,但它有效。

Note that you don't need to formally define their fields, just create them using a SELECT:请注意,您不需要正式定义它们的字段,只需使用 SELECT 创建它们:

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

(See also Create temporary table from select statement without using Create Table .) (另请参阅不使用 Create Table 从 select 语句创建临时表。)

You can achieve this in MySQL using WHILE loop:您可以使用WHILE循环在 MySQL 中实现此目的:

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;

EDIT: Alternatively you can do it using UNION ALL :编辑:或者,您可以使用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
 ...
);

Try using FIND_IN_SET() function of MySql eg尝试使用 MySql 的 FIND_IN_SET() 函数,例如

SET @c = 'xxx,yyy,zzz';

SELECT * from countries 
WHERE FIND_IN_SET(countryname,@c);

Note: You don't have to SET variable in StoredProcedure if you are passing parameter with CSV values.注意:如果您使用 CSV 值传递参数,则不必在 StoredProcedure 中设置变量。

Nowadays using a JSON array would be an obvious answer.现在使用JSON 数组将是一个明显的答案。

Since this is an old but still relevant question I produced a short example.由于这是一个古老但仍然相关的问题,我制作了一个简短的例子。 JSON functions are available since mySQL 5.7.x / MariaDB 10.2.3 JSON 函数自 mySQL 5.7.x / MariaDB 10.2.3 起可用

I prefer this solution over ELT() because it's really more like an array and this 'array' can be reused in the code.与 ELT() 相比,我更喜欢这个解决方案,因为它实际上更像一个数组,并且这个“数组”可以在代码中重用。

But be careful: It (JSON) is certainly much slower than using a temporary table.但要小心:它(JSON)肯定比使用临时表慢得多。 Its just more handy.它只是更方便。 imo.海事组织

Here is how to use a JSON array:以下是如何使用 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

And here a little example to show how it works in a function/procedure:这里有一个小例子来展示它在函数/过程中是如何工作的:

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();

Dont know about the arrays, but there is a way to store comma-separated lists in normal VARCHAR column.不知道数组,但是有一种方法可以将逗号分隔的列表存储在普通的 VARCHAR 列中。

And when you need to find something in that list you can use the FIND_IN_SET() function.当您需要在该列表中查找某些内容时,您可以使用FIND_IN_SET()函数。

I know that this is a bit of a late response, but I recently had to solve a similar problem and thought that this may be useful to others.我知道这有点晚了,但我最近不得不解决一个类似的问题,并认为这可能对其他人有用。

Background背景

Consider the table below called 'mytable':考虑下面名为“mytable”的表格:

起始表

The problem was to keep only latest 3 records and delete any older records whose systemid=1 (there could be many other records in the table with other systemid values)问题是只保留最新的 3 条记录并删除 systemid=1 的任何旧记录(表中可能有许多其他记录具有其他 systemid 值)

It would be good if you could do this simply using the statement如果您可以简单地使用该语句来做到这一点,那就太好了

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

However this is not yet supported in MySQL and if you try this then you will get an error like但是,MySQL 尚不支持此功能,如果您尝试此操作,您将收到类似的错误

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

So a workaround is needed whereby an array of values is passed to the IN selector using variable.因此需要一种解决方法,即使用变量将值数组传递给 IN 选择器。 However, as variables need to be single values, I would need to simulate an array .但是,由于变量需要是单个值,我需要模拟一个数组 The trick is to create the array as a comma separated list of values (string) and assign this to the variable as follows诀窍是将数组创建为逗号分隔的值列表(字符串)并将其分配给变量,如下所示

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);

The result stored in @myvar is存储在@myvar 中的结果是

5,6,7 5,6,7

Next, the FIND_IN_SET selector is used to select from the simulated array接下来,使用 FIND_IN_SET 选择器从模拟数组中进行选择

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

The combined final result is as follows:合并后的最终结果如下:

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);

I am aware that this is a very specific case.我知道这是一个非常具体的案例。 However it can be modified to suit just about any other case where a variable needs to store an array of values.但是,可以对其进行修改以适应变量需要存储值数组的任何其他情况。

I hope that this helps.我希望这个对你有用。

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 ;

Maybe create a temporary memory table with columns (key, value) if you want associative arrays.如果你想要关联数组,也许可以创建一个包含列(键、值)的临时内存表。 Having a memory table is the closest thing to having arrays in mysql拥有一个内存表是最接近在 mysql 中拥有数组的东西

Here's how I did it.这就是我的做法。

First, I created a function that checks whether a Long/Integer/whatever value is in a list of values separated by commas:首先,我创建了一个函数来检查 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;

So now you can search for an ID in a comma-separated list of IDs, like this:因此,现在您可以在以逗号分隔的 ID 列表中搜索 ID,如下所示:

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

And you can use this function inside a WHERE clause, like this:您可以在 WHERE 子句中使用此函数,如下所示:

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

This was the only way I found to pass an "array" parameter to a PROCEDURE.这是我发现将“数组”参数传递给 PROCEDURE 的唯一方法。

I'm surprised none of the answers mention ELT/FIELD.我很惊讶没有一个答案提到 ELT/FIELD。

ELT/FIELD works very similar to an array especially if you have static data. ELT/FIELD 的工作方式与数组非常相似,尤其是在您有静态数据的情况下。

FIND_IN_SET also works similar but doesn't have a built in complementary function but it's easy enough to write one. 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)

Is an array variable really necessary?数组变量真的有必要吗?

I ask because I originally landed here wanting to add an array as a MySQL table variable.我问是因为我最初来到这里是想添加一个数组作为 MySQL 表变量。 I was relatively new to database design and trying to think of how I'd do it in a typical programming language fashion.我对数据库设计相对较新,并试图思考如何以典型的编程语言方式来完成它。

But databases are different.但是数据库不同。 I thought I wanted an array as a variable, but it turns out that's just not a common MySQL database practice.以为我想要一个数组作为变量,但事实证明这不是常见的 MySQL 数据库实践。

Standard Practice标准实践

The alternative solution to arrays is to add an additional table, and then reference your original table with a foreign key.数组的替代解决方案是添加一个额外的表,然后使用外键引用您的原始表。

As an example, let's imagine an application that keeps track of all the items every person in a household wants to buy at the store.举个例子,让我们想象一个应用程序,它跟踪一个家庭中每个人都想在商店购买的所有物品。

The commands for creating the table I originally envisioned would have looked something like this:我最初设想的创建表的命令看起来像这样:

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

I think I envisioned buy_list to be a comma-separated string of items or something like that.我想我设想 buy_list 是一个逗号分隔的项目字符串或类似的东西。

But MySQL doesn't have an array type field, so I really needed something like this:但是 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)
);

Here we define a constraint named fk_person.这里我们定义了一个名为 fk_person 的约束。 It says that the 'person' field in BuyList is a foreign key.它说 BuyList 中的“person”字段是一个外键。 In other words, it's a primary key in another table, specifically the 'name' field in the Person table, which is what REFERENCES denotes.换句话说,它是另一个表中的主键,特别是 Person 表中的“名称”字段,这就是 REFERENCES 所表示的。

We also defined the combination of person and item to be the primary key, but technically that's not necessary.我们还定义了 person 和 item 的组合作为主键,但从技术上讲,这不是必需的。

Finally, if you want to get all the items on a person's list, you can run this query:最后,如果你想获取一个人列表中的所有项目,你可以运行这个查询:

SELECT item FROM BuyList WHERE person='John';

This gives you all the items on John's list.这为您提供了 John 列表中的所有项目。 No arrays necessary!不需要数组!

This works fine for list of values:这适用于值列表:

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;

This is my solution to use a variable containing a list of elements.这是我使用包含元素列表的变量的解决方案。 You can use it in simple queries (no need to use store procedures or create tables).您可以在简单查询中使用它(无需使用存储过程或创建表)。

I found somewhere else on the site the trick to use the JSON_TABLE function (it works in mysql 8, I dunno of it works in other versions).我在网站的其他地方发现了使用 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 ) ;

Also, you may need to manage the case of one or more variables set to empty_string .此外,您可能需要管理一个或多个变量设置为empty_string的情况。 In this case I added another trick (the query does not return error even if x , y , or both x and y are empty strings):在这种情况下,我添加了另一个技巧(即使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) ;

Both versions using sets didn't work for me (tested with MySQL 5.5).使用集合的两个版本都不适合我(用 MySQL 5.5 测试)。 The function ELT() returns the whole set.函数 ELT() 返回整个集合。 Considering the WHILE statement is only avaible in PROCEDURE context i added it to my solution:考虑到 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__;

To be honest, i don't think this is a good practice.老实说,我认为这不是一个好习惯。 Even if its realy necessary, this is barely readable and quite slow.即使它真的有必要,这也很难读,而且速度很慢。

Isn't the point of arrays to be efficient?数组不是要高效吗? If you're just iterating through values, I think a cursor on a temporary (or permanent) table makes more sense than seeking commas, no?如果您只是遍历值,我认为临时(或永久)表上的游标比寻找逗号更有意义,不是吗? Also cleaner.也更干净。 Lookup "mysql DECLARE CURSOR".查找“mysql DECLARE CURSOR”。

For random access a temporary table with numerically indexed primary key.对于随机访问具有数字索引主键的临时表。 Unfortunately the fastest access you'll get is a hash table, not true random access.不幸的是,您将获得的最快访问是哈希表,而不是真正的随机访问。

Another way to see the same problem.看到同样问题的另一种方式。 Hope helpfull希望有帮助

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,');

If we have one table like that如果我们有一张这样的桌子

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

and the array table:和数组表:

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 |

We can select the rows of the second table as one array with CONCAT function:我们可以使用 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         |
+------------+-------+--------+------------+-------------+

In MYSQL version after 5.7.x, you can use JSON type to store an array.在 MYSQL 5.7.x 之后的版本中,可以使用 JSON 类型来存储数组。 You can get value of an array by a key via MYSQL.您可以通过 MYSQL 通过键获取数组的值。

Inspired by the function ELT(index number, string1, string2, string3,…),I think the following example works as an array example:受函数 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;

Hope it help.希望它有所帮助。

Here is an example for MySQL for looping through a comma delimited string.这是一个用于循环逗号分隔字符串的 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;

this uses the get_from_delimiter_split_string function defined here: https://stackoverflow.com/a/59666211/3068233这使用此处定义的get_from_delimiter_split_string函数: https ://stackoverflow.com/a/59666211/3068233

I Think I can improve on this answer.我想我可以改进这个答案。 Try this:尝试这个:

The parameter 'Pranks' is a CSV.参数“恶作剧”是一个 CSV。 ie. IE。 '1,2,3,4.....etc' '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;

This method makes the searched string of CSV values progressively shorter with each iteration of the loop, which I believe would be better for optimization.这种方法使搜索到的 CSV 值字符串随着循环的每次迭代而逐渐变短,我相信这对于优化来说会更好。

I would try something like this for multiple collections.我会为多个收藏尝试这样的事情。 I'm a MySQL beginner.我是 MySQL 初学者。 Sorry about the function names, couldn't decide on what names would be best.对函数名称感到抱歉,无法确定最好的名称。

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');

Rather than Saving data as a array or in one row only you should be making diffrent rows for every value received.而不是将数据保存为数组或仅保存在一行中,您应该为收到的每个值制作不同的行。 This will make it much simpler to understand rather than putting all together.这将使它更容易理解,而不是放在一起。

Have you tried using PHP's serialize()?你试过使用 PHP 的 serialize() 吗? That allows you to store the contents of a variable's array in a string PHP understands and is safe for the database (assuming you've escaped it first).这允许您将变量数组的内容存储在 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());

You can also do the exact same without a numbered array您也可以在没有编号数组的情况下执行完全相同的操作

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

or或者

$array3 = array(
    'somethingNew'
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM