如何在不使用存储过程的情况下编写在MySql中运行n次的循环。
这是我使用存储过程的方法:
DELIMITER $$
DROP PROCEDURE IF EXISTS test$$
CREATE PROCEDURE test()
BEGIN
DECLARE count INT DEFAULT 0;
WHILE count < 10 DO
/**Sql statement**/
SET count = count + 1;
END WHILE;
END$$
DELIMITER ;
然后我以这种方式执行我的程序:
call test();
如果我删除存储过程并运行正常查询,则它会因此错误而失败:
1064 - 您的SQL语法出错;检查与您的MySQL服务器版本相对应的手册,以获得正确的语法,以便在DECLARE计数附近使用INT DEFAULT 0;数量&lt; 10 DO在线&#39; 2
我已经通过互联网查找了没有运气的解决方案。
根据评论进行编辑:
上面的存储过程完全符合我的要求:它循环10次并执行我的sql语句。现在我想在不使用存储过程的情况下完成同样的事情。类似的东西:
DECLARE count INT DEFAULT 0;
WHILE count < 10 DO
/**Sql statement**/
SET count = count + 1;
END WHILE;
答案 0 :(得分:12)
Flow Control Statements上的MySQL文档说:
MySQL支持IF,CASE,ITERATE,LEAVE LOOP,WHILE和REPEAT 流程控制的构造在存储的程序中。
Stored Programs and Views上的文档说:
存储的程序定义包括可能使用化合物的主体 语句,循环,条件和声明的变量。
本节介绍BEGIN ... END化合物的语法 语句和其他语句可以在存储的主体中使用 程序:存储过程和函数,触发器和事件。
复合语句是一个可以包含其他块的块; 变量,条件处理程序和游标的声明;并且流动 控制构造,如循环和条件测试。
因此,看起来您只能在存储过程,函数或触发器中运行显式循环。
根据您在SQL语句中的操作,可以使用数字表(或视图)(Creating a "Numbers Table" in mysql,MYSQL: Sequential Number Table)。
如果您的查询是SELECT
并且可以将SELECT
的结果作为一个长结果集返回10次(而不是10个单独的结果集),则可以执行以下操作:
SELECT MainQuery.*
FROM
(
SELECT 1 AS Number
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
) AS Numbers
CROSS JOIN
(
SELECT 'some data' AS Result
) AS MainQuery
INSERT示例
我建议在数据库中有一个永久的数字表。在许多情况下它很有用。请参阅上面的链接如何生成它。
因此,如果您的表Numbers
int
列Number
的值为1到100K(就像我一样),并且此列上有主键,那么而不是这个循环:
DECLARE count INT DEFAULT 0;
WHILE count < 10 DO
INSERT INTO table_name(col1,col2,col3)
VALUES("val1","val2",count);
SET count = count + 1;
END WHILE;
你可以写:
INSERT INTO table_name(col1,col2,col3)
SELECT ("val1", "val2", Numbers.Number-1)
FROM Numbers
WHERE Numbers.Number <= 10;
它的工作速度也快了近10倍。
答案 1 :(得分:1)
这是不可能的。
我阅读了所有MySQL文档,它只能在函数/过程体中声明。
答案 2 :(得分:1)
DECLARE @count INT = 0;
WHILE @count < 10
BEGIN
DELETE TOP (300)
FROM EmployeeInformation
WHERE IsSynced=1 and CreatedDate<'2020-02-29'
SET @count = @count + 1;
END
此代码对我有用。
答案 3 :(得分:0)
正如Berd所提到的,您可以使用内置顺序执行此操作,但这有点奇怪:
SET @i = 1;
set @str = 'a,b,c,d,e,f,g,h';
select temp.length into @length from
(select
ROUND(
(
LENGTH(dt.data)
- LENGTH( REPLACE (dt.data, ",", "") )
) / LENGTH(",")
)+1 AS length
from (select @str as data) dt
) temp;
SET @query = CONCAT('select substring_index(
substring_index(@str, '','', seq),
'','',
-1
) as letter from seq_', @i, '_to_',@length);
PREPARE q FROM @query;
EXECUTE q;