ein*_*ica 76 mysql arrays variables set temp-tables
这似乎是MySQL没有数组变量.我应该用什么呢?
似乎有两种选择建议:集类型标量和临时表.我联系的问题暗示了前者.但是使用这些而不是数组变量是一种好习惯吗?或者,如果我使用集合,那么基于集合的成语相当于foreach什么?
ein*_*ica 65
好吧,我一直在使用临时表而不是数组变量.不是最好的解决方案,但它确实有效.
请注意,您无需正式定义其字段,只需使用SELECT创建它们:
CREATE TEMPORARY TABLE IF NOT EXISTS my_temp_table
SELECT first_name FROM people WHERE last_name = 'Smith';
Run Code Online (Sandbox Code Playgroud)
(另请参阅从select语句创建临时表而不使用Create Table.)
Ome*_*esh 38
您可以使用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;
Run Code Online (Sandbox Code Playgroud)
编辑:或者你可以使用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
...
);
Run Code Online (Sandbox Code Playgroud)
Him*_*arg 22
尝试使用MySql的FIND_IN_SET()函数,例如
SET @c = 'xxx,yyy,zzz';
SELECT * from countries
WHERE FIND_IN_SET(countryname,@c);
Run Code Online (Sandbox Code Playgroud)
注意:如果要使用CSV值传递参数,则不必在StoredProcedure中设置SET变量.
Sep*_*ity 12
现在使用JSON数组将是一个明显的答案.
由于这是一个古老但仍然相关的问题,我提出了一个简短的例子.自mySQL 5.7.x/MariaDB 10.2.3起,JSON函数可用
我比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
Run Code Online (Sandbox Code Playgroud)
这里有一个小例子来说明它在函数/过程中是如何工作的:
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();
Run Code Online (Sandbox Code Playgroud)
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 ;
Run Code Online (Sandbox Code Playgroud)
我知道这有点晚了,但我最近不得不解决一个类似的问题,并认为这可能对其他人有用。
背景
考虑下面名为“mytable”的表格:
问题是只保留最新的 3 条记录并删除 systemid=1 的所有旧记录(表中可能有许多其他记录具有其他 systemid 值)
最好是你可以简单地使用语句来做到这一点
DELETE FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)
Run Code Online (Sandbox Code Playgroud)
但是,MySQL 尚不支持此功能,如果您尝试此操作,则会出现类似错误
...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'
Run Code Online (Sandbox Code Playgroud)
因此需要一种变通方法,即使用变量将一组值传递给 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);
Run Code Online (Sandbox Code Playgroud)
存储在@myvar 中的结果是
5,6,7
接下来使用 FIND_IN_SET 选择器从模拟数组中进行选择
SELECT * FROM mytable WHERE FIND_IN_SET(id,@myvar);
Run Code Online (Sandbox Code Playgroud)
合并后的最终结果如下:
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);
Run Code Online (Sandbox Code Playgroud)
我知道这是一个非常具体的案例。然而,它可以被修改以适应变量需要存储值数组的任何其他情况。
我希望这个对你有用。
| 归档时间: |
|
| 查看次数: |
289550 次 |
| 最近记录: |