MySQL 准备语句 - 如何循环

2024-04-02

我有一个充满 ID 号的表,我需要循环遍历该表,并将其用作准备好的语句中的变量。我不知道是否需要为此使用存储过程,或者常规查询是否可以做到这一点。这是一个简单的例子。

SELECT id from var_list;

loop through @ID = var_list.id ....


SET @s1 = "SELECT * FROM data WHERE id = @ID"; 
PREPARE stmt1 FROM @s1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

正如评论中提到的,我只需要它来导出一些数据,我的表中有大约 50-100 个 ID,并且编写了一个查询来一次将一个文件导出到服务器。

编辑 我计划使用类似......的东西将每次迭代的结果转储到文件中。

INTO OUTFILE '/tmp/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'

正如其他人已经建议的那样,我们通常avoid循环遍历结果集RBAR(逐行排列)主要是出于性能原因。我们只是不想养成循环结果集的习惯。但这并不能回答你提出的问题。

为了回答您提出的问题,这里有一个 MySQL 存储程序的基本示例,该程序使用 CURSOR 单独处理查询返回的行。 MySQL 不支持匿名块,因此唯一的方法是在 MySQL 存储程序中,例如 PROCEDURE

DELIMITER $$

CREATE PROCEDURE loop_through_var_list
BEGIN
   DECLARE done INT DEFAULT 0;
   DECLARE v_id INT DEFAULT NULL;  
   DECLARE csr_var_list CURSOR FOR SELECT id FROM var_list ORDER BY id;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
   OPEN csr_var_list;
   get_id: LOOP
      FETCH csr_var_list INTO v_id; 
      IF done = 1 THEN
         LEAVE get_id;
      END IF;

      -- at this point, we have an id value in v_id, so we can do whatever
      SET @s1 = CONCAT('SELECT ... WHERE id =''', v_id, ''' ...');


   END LOOP get_id;
   CLOSE csr_var_list;
END$$

DELIMITER ;

要执行该过程:

CALL loop_through_var_list();

注意:MySQL 中处理 CURSOR 的语法与其他数据库有很大不同。

为了获得“循环”,我们需要使用LOOP ... END LOOP构造。

但为了防止该循环永远运行,我们需要一个 LEAVE 语句来允许我们退出循环。

我们使用条件测试来确定何时离开。在此示例中,我们希望在处理完最后一行后退出。

The FETCH当没有更多的行可供获取时,将引发异常。

我们在 CONTINUE HANDLER 中“捕获”该异常(由于某些神秘的原因,“处理程序”必须声明最后的内容;如果我们尝试在 HANDLER 之后声明某些内容(而不是另一个 HANDLER),MySQL 会抛出错误。)

当 MySQL 抛出“no more rows”异常时,会触发处理程序代码。在此示例中,我们只是设置一个变量(名为done) 到一个值。

由于它是一个“继续”处理程序,因此处理会在引发异常的语句处重新开始,在本例中,这将是 FETCH 之后的语句。因此,我们要做的第一件事就是检查我们是否“完成”。如果我们“完成”,那么我们退出循环,并关闭光标。

否则,我们知道我们有一个id价值来自var_list存储在名为的过程变量中v_id。所以现在我们可以做任何我们想做的事。看起来您想将一些 SQL 文本放入用户定义的变量中(包括将 v_id 的值放入 SQL 文本中,然后 PREPARE、EXECUTE 和 DEALLOCATE PREPARE。

请务必声明v_id具有适当数据类型的变量,该变量与id列于var_list,我只是假设它是一个 INT。

当我们到达循环末尾时,MySQL“循环”回到循环的开头,然后再次开始。

在循环体中,您可能需要将 v_id CONCAT 到要执行的 SQL 文本中。看起来您已经掌握了 PREPARE、DEALLOCATE 准备。为了进行测试,您可能需要在游标声明中的 SELECT 上添加 LIMIT 子句,然后执行简单的 SELECT v_id;在正文中,只是为了在添加更多代码之前验证循环是否正常工作。


FOLLOWUP

我想提到该任务的另一种替代方法,即基于模板运行一系列语句,替换单个 SQL select 语句提供的值...

例如,如果我有这个模板:

SELECT * 
  INTO OUTFILE '/tmp/[email protected] /cdn-cgi/l/email-protection'
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
FROM data 
WHERE id = @ID
ORDER BY 1 

我需要将出现的 @ID 替换为 SELECT 语句返回的列表中的特定 id 值,例如

SELECT id
  FROM var_list
 WHERE id IS NOT NULL
 GROUP BY id

我可能不会使用带有 CURSOR 循环的 MySQL 存储程序,我会使用不同的方法。

我将使用 SELECT 语句来生成一组可以执行的 SQL 语句。假设id是整数类型,我可能会这样做:

SELECT CONCAT(' SELECT * 
                   INTO OUTFILE ''/tmp/orders_',s.id,'.csv''
                   FIELDS TERMINATED BY '','' ENCLOSED BY ''"''
                   LINES TERMINATED BY ''\n''
                FROM data
               WHERE id = ',s.id,'
               ORDER BY 1;') AS `stmt`
 FROM ( SELECT v.id
          FROM var_list v
         WHERE v.id IS NOT NULL
         GROUP BY v.id
      ) s
ORDER BY s.id

对于每个值id从返回s,该语句返回可以(并且需要)执行的 SQL SELECT 语句的文本。将其捕获到文本文件中将为我提供一个可以运行的 SQL 脚本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL 准备语句 - 如何循环 的相关文章

  • 无法在 Mac 上启动 MySQL

    使用 Brew 安装后 我无法运行 MySQL 我使用的是 OS X El Capitan 版本 10 11 3 和 MySQL Server 版本 5 7 11 当我启动服务器时 我收到 启动 MySQL 错误 服务器退出而不更新 PID
  • 如何通过子 POJO 的属性过滤复合 ManyToMany POJO?

    我有两个像这样的房间实体 Entity public class Teacher implements Serializable PrimaryKey autoGenerate true public int id ColumnInfo n
  • 非常大的字段会对 MySQL 数据库产生负面影响吗?

    我目前正在使用 Django 构建一个网站 并希望托管用户生物样式页面 该页面可能长达几 KB 这些字段不一定需要搜索 但在查找用户名时确实需要提供 将这些数据存储在数据库中会产生负面影响吗 如果我使用带有数据库链接的静态文本文件 我的服务
  • 实现软删除的最佳方法是什么?

    目前在做一个项目 我们要对大部分用户 用户角色 实现软删除 我们决定添加一个is deleted 0 数据库中每个表的字段并将其设置为 1 如果特定用户角色点击特定记录上的删除按钮 现在为了将来的维护 每个SELECT查询需要确保它们不包含
  • 快速查询最新记录的方法?

    我有一张这样的表 USER PLAN START DATE END DATE 1 A 20110101 NULL 1 B 20100101 20101231 2 A 20100101 20100505 在某种程度上 如果END DATE i
  • 在 SQL Server 上执行分页的最佳方式是什么?

    我有一个数据库超过200万记录 我需要执行分页以在我的 Web 应用程序上显示 该应用程序每页必须有 10 条记录DataGrid 我已经尝试使用ROW NUMBER 但是这种方式会选择所有 200 万条记录 然后只得到 10 条记录 我也
  • 在 SQL 中,如何从 SELECT * FROM ... 中排除结果?

    我知道我的标题不太具有描述性 让我在这里详细解释一下 假设一个表有 26 个字段 例如字段 a 字段 z 我只想要一个选择查询只返回 15 个字段 所以 通常 我会执行 SELECT field a field b field o FROM
  • PHP MySQL 使用选项/选择 HTML 表单标签进行多重搜索查询

    我正在尝试使用两个搜索字段设置基本的 MySQL LIKE 搜索 我不想拥有它 所以它有多个可选搜索字段 例如if isset POST city isset POST name 我不知道如何用 HTML 来做到这一点
  • 如何检测Mysql/innodb中的死锁?

    我知道在 Innodb 中使用事务时不可避免地会发生死锁 并且如果应用程序代码正确处理死锁 它们是无害的 正如手册所说 只需再试一次 所以我想知道 如何检测死锁 死锁是否会发出一些特殊的 mysql 错误号 如果重要的话 我正在使用 PHP
  • MYSQL - 使用逗号分隔字符串作为变量输入的存储过程

    我希望有人能够提供帮助 我已经创建了我的第一个存储过程 没什么花哨的 但是我遇到了问题 我想给它一个字符串输入 例如 1 2 3 4 5 然后它执行一个简单的操作SELECT FROM TABLE WHERE EAN IN VAR 所以存储
  • posts_search 中的自定义查询

    如何使用此查询作为我的自定义搜索查询 add filter posts search my search is perfect 20 2 function my search is perfect search wp query sWord
  • 数字表与递归 CTE 生成一系列数字

    为什么使用数字表比使用递归 CTE 动态生成它们要快得多 在我的机器上 给定一张桌子numbers单列n 主键 包含从1到100000的数字 查询如下 select n from numbers 大约需要 400 毫秒才能完成 使用递归 C
  • 从 Getdate() 获取时间

    我想采取Getdate 结果 例如 2011 10 05 11 26 55 000 into 11 26 55 AM 我看过其他地方并发现 Select RIGHT CONVERT VARCHAR GETDATE 100 7 这给了我 11
  • SQL查询查找表的主键?

    我怎样才能找到哪一列首要的关键使用查询来创建表 这是重复的question https stackoverflow com questions 893874 mysql determine tables primary key dynami
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec
  • 学说迁移后备

    我们正在使用原则迁移 当迁移包含多个操作并且其中一个操作失败时 通常会出现问题 例如 如果迁移添加了 5 个外键 其中第 5 个失败 而字段长度不同 则修复字段错误并重新生成迁移不会not修复整个问题 而现在出现一个与 4 个密钥已存在有关
  • 从Django中具有外键关系的两个表中检索数据? [复制]

    这个问题在这里已经有答案了 This is my models py file from django db import models class Author models Model first name models CharFie
  • 随机组合 MySQL 数据库中的两个单词

    我有一个包含名词和形容词的数据库 例如 id type word 1 noun apple 2 noun ball 3 adj clammy 4 noun keyboard 5 adj bloody ect 我想创建一个查询 它将抓取 10
  • 我是否需要在外键上指定 ON DELETE NO ACTION?

    我有以下与 SQL Server 2012 一起使用的 DDL CREATE TABLE Subject SubjectId INT IDENTITY 1 1 NOT NULL Name NVARCHAR 50 Not NULL CONST
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装

随机推荐