从 .sql 文件顺序调用存储过程

2023-12-02

我被困在这里了。

我有一个程序,我想连续运行 X* 次。 (*X 是几千次)
基于输入数据的过程执行以下操作:
1. 查找 actions.id,如果没有找到LEAVEs.
2.查找users.id,如果没有找到,则创建一个并使用LAST_INSERT_ID();
3-5。查找 summaries.id(3 种类型,总计、每日和每月),如果未找到,则创建一个并使用其 ID。
6. 收集完所有必需的 ID 后,INSERT将新行放入操作中,并更新事务中的摘要行,因此如果有任何失败 - 它会执行ROLLBACK- 没有造成任何伤害。
7. 取决于结果SELECT的消息。

CREATE PROCEDURE NEW_ACTION(
  IN a_date TIMESTAMP,
  IN u_name VARCHAR(255),
  IN a_name VARCHAR(255),
  IN a_chars INT,
  IN url VARCHAR(255),
  IN ip VARCHAR(15))

  lbl_proc: BEGIN
    DECLARE a_id, u_id, us_id, usd_id, usm_id, a_day, a_month, error INT;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET error = 1;

    SET error = 0;
    SET a_day = DATE_FORMAT(SUBSTRING(a_date ,1,10), '%Y%m%d');
    SET a_month = SUBSTRING(a_day, 1, 6);

    /* 1. RETREIVING action.id */
    SET a_id = (SELECT `id` FROM `actions` WHERE `name` = a_name);
    IF a_id IS NULL THEN
      SELECT 'error';
      LEAVE lbl_proc;
    END IF;

    /* 2. RETREIVING users.id */
    SET u_id = (SELECT `id` FROM `users` WHERE `name` = u_name);
    IF u_id IS NULL THEN
      INSERT INTO `users` (name) VALUES (u_name);
      SET u_id = (SELECT LAST_INSERT_ID());
    END IF;

    /* 3. RETREIVING user_summaries.id */
    SET us_id = (SELECT `id` FROM `users_summaries` WHERE `user_id` = u_id AND `action_id` = a_id);
    IF us_id IS NULL THEN
      INSERT INTO `users_summaries` (user_id, action_id) VALUES (u_id, a_id);
      SET us_id = (SELECT LAST_INSERT_ID());
    END IF;

    /* 4. RETREIVING user_summaries_days.id */
    SET usd_id = (SELECT `id` FROM `users_summaries_days` WHERE `day` = a_day AND `user_id` = u_id AND `action_id` = a_id);
    IF usd_id IS NULL THEN
      INSERT INTO `users_summaries_days` (day, user_id, action_id) VALUES (a_day, u_id, a_id);
      SET usd_id = (SELECT LAST_INSERT_ID());
    END IF;

    /* 5. RETREIVING user_summaries_months.id */
    SET usm_id = (SELECT `id` FROM `users_summaries_months` WHERE `month` = a_month AND `user_id` = u_id AND `action_id` = a_id);
    IF usm_id IS NULL THEN
      INSERT INTO `users_summaries_months` (month, user_id, action_id) VALUES (a_month, u_id, a_id);
      SET usm_id = (SELECT LAST_INSERT_ID());
    END IF;

    /* 6. SAVING action AND UPDATING summaries */
    SET autocommit = 0;
    START TRANSACTION;
      INSERT INTO `users_actions` (`date`, `user_id`, `action_id`, `chars`, `url`, `ip`) VALUES (a_date, u_id, a_id, a_chars, url, ip);
      UPDATE `users_summaries` SET qty = qty + 1, chars = chars + a_chars WHERE id = us_id;
      UPDATE `users_summaries_days` SET qty = qty + 1, chars = chars + a_chars WHERE id = usd_id;
      UPDATE `users_summaries_months` SET qty = qty + 1, chars = chars + a_chars WHERE id = usm_id;

      IF error = 1 THEN
        SELECT 'error';
        ROLLBACK;
        LEAVE lbl_proc;
      ELSE
        SELECT 'success';
        COMMIT;
      END IF;
  END;

现在,我已经获得了想要输入到此过程中的原始数据。目前大约有 3000 行。

我尝试了所有我知道的解决方案:

A. # mysql -uuser -ppass DB < calls.sql- 使用 php 我基本上创建了一个这样的调用列表:

CALL NEW_ACTION('2010-11-01 13:23:00', 'username1', 'actionname1', '100', 'http://example.com/', '0.0.0.0');  
CALL NEW_ACTION('2010-11-01 13:23:00', 'username2', 'actionname1', '100', 'http://example.com/', '0.0.0.0');  
CALL NEW_ACTION('2010-11-01 13:23:00', 'username1', 'actionname2', '100', 'http://example.com/', '0.0.0.0');  
...

这总是在第 452 行失败(尝试了几次),它发现了两个摘要 ID(步骤 3)。
我认为这可能是由于之前(第 375-376 行)有人要求同一用户执行相同的操作。
好像mysql没有及时更新表,所以创建的汇总行CALL当执行第 376 行时,第 375 行中的内容尚不可见 - 因此创建另一个摘要行。
我以为我会尝试延迟通话...

B.使用mysql的SLEEP(duration).
这并没有改变任何事情。执行再次在同一个 CALL 处停止。

我现在没有主意了。
非常感谢建议和帮助。

NOTE:操作名称和用户名重复。

附言。请记住,这是我编写的第一个程序之一。
PS2。运行 mysql 5.1.52-community-log 64 位(Windows 7U)、PHP 5.3.2 和 Apache 2.2.17


EDIT

我已将问题中与 PHP 相关的部分删除这里有单独的问题.


EDIT2

好的,我已从 .sql 文件中删除了前 200 个调用。由于某种原因,它很好地超越了停止执行的前一行。现在它停在第 1618 行。
这意味着,在某一时刻,新的INSERTed摘要行暂时不可见,因此当发生以下迭代之一想要SELECT他们还无法访问它。这是 MySQL 的错误吗?


EDIT3

现在我注意到另一件有趣的事情。我调查了两个 users_summaries 的创建位置。当有两个 CALL 引用相同的内容时,就会发生这种情况(并非总是如此,但如果,那么就会发生)user and action非常接近。它们可能彼此相邻,也可能被 1 或 2 个不同的呼叫分开。

如果我将其中之一(在 .sql 文件内)移动 50-100 行(较早执行)就可以了。我什至设法使 .sql 文件作为一个整体工作。但这仍然没有真正解决问题。 3000 行还不错,但如果有 100000 行,我就迷路了。我不能依赖对 .sql 文件的手动调整。


这并不是真正的解决方案,而是一种解决方法。

只是为了澄清,汇总表有id列为PRIMARY KEY with AUTO_INCREMENT两者的选项和索引user_id and action_id column.

我的调查表明,虽然我的程序正在寻找一个条目existed using WHERE user_id = u_id AND action_id = a_id在某些情况下,它没有发现它导致新行被插入相同的行user_id and action_id价值观——我不想要的东西。

调试程序显示我正在寻找的摘要行,尽管无法通过WHERE user_id = u_id AND action_id = a_id条件,调用它时正确返回id - PRIMARY KEY.
有了这个发现,我决定改变格式id栏目,来自UNASIGNED INT with AUTO_INCEREMENT to a CHAR(32)其中包括:

<user_id>|<action_id>

这意味着我确切地知道什么是id我想要的行甚至在它存在之前。这确实解决了问题。它还使我能够使用INSERT ... ON DUPLICATE KEY UPDATE ...构造。

下面是我更新的程序:

CREATE PROCEDURE `NEW_ACTION`(
  IN a_date TIMESTAMP,
  IN u_name VARCHAR(255),
  IN a_name VARCHAR(255),
  IN a_chars INT,
  IN url VARCHAR(255),
  IN ip VARCHAR(15))
  SQL SECURITY INVOKER

lbl_proc: BEGIN
    DECLARE a_id, u_id, a_day, a_month, error INT;
    DECLARE us_id, usd_id, usm_id CHAR(48);
    DECLARE sep CHAR(1);
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET error = 1;

    SET sep = '|';
    SET error = 0;
    SET a_day = DATE_FORMAT(SUBSTRING(a_date ,1,10), '%Y%m%d');
    SET a_month = SUBSTRING(a_day, 1, 6);

    /* RETREIVING action.id */
    SET a_id = (SELECT `id` FROM `game_actions` WHERE `name` = a_name);
    IF a_id IS NULL THEN
      SELECT 'error';
      LEAVE lbl_proc;
    END IF;

    /* RETREIVING users.id */
    SET u_id = (SELECT `id` FROM `game_users` WHERE `name` = u_name);
    IF u_id IS NULL THEN
      INSERT INTO `game_users` (name) VALUES (u_name);
      SET u_id = LAST_INSERT_ID();
    END IF;

    /* SETTING summaries ids */
    SET us_id = CONCAT(u_id, sep, a_id);
    SET usd_id = CONCAT(a_day, sep, u_id, sep, a_id);
    SET usm_id = CONCAT(a_month, sep, u_id, sep, a_id);

    /* SAVING action AND UPDATING summaries */
    SET autocommit = 0;
    START TRANSACTION;
      INSERT INTO `game_users_actions` (`date`, `user_id`, `action_id`, `chars`, `url`, `ip`)
        VALUES (a_date, u_id, a_id, a_chars, url, ip);
      INSERT INTO `game_users_summaries` (`id`, `user_id`, `action_id`, `qty`, `chars`)
        VALUES (us_id, u_id, a_id, 1, a_chars)
        ON DUPLICATE KEY UPDATE qty = qty + 1, chars = chars + a_chars;
      INSERT INTO `game_users_summaries_days` (`id`, `day`, `user_id`, `action_id`, `qty`, `chars`)
        VALUES (usd_id, a_day, u_id, a_id, 1, a_chars)
        ON DUPLICATE KEY UPDATE qty = qty + 1, chars = chars + a_chars;
      INSERT INTO `game_users_summaries_months` (`id`, `month`, `user_id`, `action_id`, `qty`, `chars`)
        VALUES (usm_id, a_month, u_id, a_id, 1, a_chars)
        ON DUPLICATE KEY UPDATE qty = qty + 1, chars = chars + a_chars;   

      IF error = 1 THEN
        SELECT 'error';
        ROLLBACK;
        LEAVE lbl_proc;
      ELSE
        SELECT 'success';
        COMMIT;
      END IF;
  END

无论如何,我仍然认为 MySQL 中存在某种错误,但我认为问题已解决。

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

从 .sql 文件顺序调用存储过程 的相关文章

  • Mysql - Mysql2::错误:字符串值不正确:

    所以我建造了一个刮刀并拉动一些物体 问题是有些是外语 它使 mysql 数据库有点崩溃 这是我得到的错误 知道我能用这个做什么吗 谢谢 Mysql2 错误 列的字符串值不正确 xC5 x8Dga 第 1 行的 描述 插入sammiches
  • 通过我的java代码导出数据库

    我想使用我的 java 代码导出我的 MySQL 数据库 但我还没有找到任何办法 我想要做的就是我的应用程序中有一个按钮作为 导出数据库 单击该按钮时 我的数据库应导出到指定的路径 我使用了以下代码 但它不起作用 Runtime runti
  • 在 MySQL 数据库中存储图像文件或 URL?哪个更好? [复制]

    这个问题在这里已经有答案了 可能的重复 在数据库中存储图像 是还是否 https stackoverflow com questions 3748 storing images in db yea or nay 数据库中的图像与文件系统中的
  • MySQL Workbench 6.0 错误无法获取管理员的管理访问权限?

    我在这里使用 MySQL Workbench 6 0 当我选择服务器状态时 出现此错误 对此 我尝试在Google和StackOverflow上寻找解决方案 e g 这个结果 https stackoverflow com question
  • 使用唯一索引删除重复项

    我在两个表字段 A B C D 之间插入 相信我已经在 A B C D 上创建了唯一索引以防止重复 然而我以某种方式简单地对这些做了一个正常的索引 因此插入了重复项 这是2000万条记录的表 如果我将现有索引从普通索引更改为唯一索引 或者只
  • mysql语句中的*星号是什么意思?

    Ex mysql query SELECT FROM members WHERE id id 这意味着选择表中的所有列
  • 通过货币换算获取每种产品类型的最低价格

    我想选择每种产品类型中最便宜的 包括运费 价格转换为当地货币 最便宜 产品 价格 产品 运费 seller to aud 我的数据库有如下表 PRODUCTS SELLERS id type id seller id price shipp
  • 无法使用 Django 应用程序从容器连接到 MySQL docker 容器

    当我尝试从运行 Django 应用程序的 docker 容器连接到运行 MySQL 的容器时 出现以下错误 django db utils OperationalError 2003 Can t connect to MySQL serve
  • MySQL 全文搜索不适用于某些单词,例如“house”

    我已经在 3 个字段中的一小部分记录上设置了全文索引 也尝试了 3 个字段的组合 并得到了相同的结果 有些单词返回结果很好 但某些单词如 house 和 澳大利亚 不这样做 有趣的是 澳大利亚 和 家乡 这样做 这似乎是奇怪的行为 如果我添
  • 社交应用程序的数据库设计和优化注意事项

    通常的情况 我有一个简单的应用程序 允许人们上传照片并关注其他人 因此 每个用户都会有类似 墙 或 活动源 的东西 他或她可以在其中看到他 她的朋友 他或她关注的人 上传的最新照片 大多数功能都很容易实现 然而 当涉及到这个历史活动源时 由
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • Mysql innoDB 不断崩溃[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的数据库 mysql 服务器不断崩溃 重新启动 我不知道该怎么办 我不断在 dbname org err 文件中收到以下内容 13120
  • 使 pdo::query 静态

    当我运行下面的代码时出现此错误 我通常使用 msql 函数 但我尝试使用 PDO 代替 怎么了 致命错误 第 14 行无法静态调用非静态方法 PDO query
  • 无法启动 MySQL 服务器 - 控制进程退出并出现错误代码

    我的 mysql 服务器停止后无法启动 命令使用 sudo etc init d mysql restart Error 重新启动 mysql 通过 systemctl mysql serviceJob for mysql service
  • 查询中列的顺序重要吗?

    当从 MySQL 表中选择列时 与表中的顺序相比 选择列的顺序是否会影响性能 不考虑可能覆盖列的索引 例如 您有一个包含行 uid name bday 的表 并且有以下查询 SELECT uid name bday FROM table M
  • 当sql连接中存在两个同名列时,如何从一个表列中获取值

    当我连接两个具有相同名称列的表时 我目前面临着尝试获取值的问题 例如 table1 date和table2 date 每个表中的日期不同 我将如何获取 日期 本例中的表1 我目前正在跑步 while row mysqliquery gt f
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • MySQL MIN/MAX 所有行

    我有桌子Races与行ID Name and TotalCP 我选择分钟 TotalCP FROM Races 但是我想选择具有最小值的整行 我如何在单个查询中做到这一点 从聚合值获取整行的一般形式是 SELECT FROM Races W
  • 如何在存储过程中实现 sql 搜索功能 (Sql Server 2008)

    我需要编写一个存储过程 该过程将使用 sql server 2008 根据可选参数搜索表 将会有两种模式 基本搜索模式 我们只传递一些文本 高级搜索模式 使用可选参数而不使用 SearchText 为了进行测试 我使用 AdventureW
  • 忽略重复条目并在 EF Core 中的 DbContext.SaveChanges() 上提交成功条目

    我有一个 ASP Net Core 2 2 Web API 在我的一个控制器操作中 我向 MySQL 数据库表添加了一堆行 我使用的是 Pomelo 例如 dbContext AddRange entities dbContext Save

随机推荐

  • 重试之前的任务操作 TPL

    我想实现一个重试任务 该任务采用先前失败的任务操作并重复它 这是我到目前为止所拥有的 然而 它只是重复任务出错的事实 而不是再次实际触发任务的操作 public static async Task
  • Accept* HTTP 标头中的 q=0.5 是什么?

    Accept text html application xhtml xml application xml q 0 9 q 0 8 Accept Language en us en q 0 5 Accept Charset ISO 885
  • 如何在控制台项目中使用 Main() 启动窗口?

    我有一个控制台项目 但现在我需要放置一个用户界面 所以我使用 3 层模型 演示 业务 访问数据 按照我的方法Main 我调用的是表示层 比如Window形式的app或者Wpf 所以 在表示层就是通过CONSOLE与用户交互 现在 我在表示层
  • 运行 Android 应用程序时出现持续问题

    我在使用 Android 应用程序时遇到了非常困难的时期 我正在使用 Eclipse V 4 2 0 并运行 API 版本 7 下面是我遇到困难的一个程序的 LogCat 输出 这是我的代码 Manifest
  • Selenium WebDriver 和 Selenium 服务器

    我需要你的帮助来连接与硒相关的东西 在过去的几周里 我一直在阅读有关 Selenium 的文档 有selenium IDE 用于记录和重放测试的firefox扩展 硒 RC 硒 1 0 现在似乎已弃用 并使用代理 HTTP 服务器在多个浏览
  • IOS JSON 反序列化失败 - STIG/NSJSONSerializer

    我想反序列化从 IOS 中运行的 Web 服务收到的简单 JSON NickName James Roeiter3 TempId 634783760669935686 LDAP XUserName15 SecToken null NickN
  • OPENGL用户界面编程[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在开发一个图形应用程序来呈现数据 不是游戏 而是真正的主力应用程序 它需要跨平台 所以我选择了 python openGL 我需要 3D 混合
  • Excel VBA 循环遍历数据透视项

    我想循环遍历我的数据透视项并检查它们是否存在于另一个表中 请参阅我的示例屏幕截图 所以我想循环遍历所有颜色 检查它们是否存在于另一个表中 例如在另一个表中 有什么办法可以做到这一点 这样就会出现一个消息框 提示在列表中找不到紫色 非常感谢您
  • 如何在shell脚本中增加版本号?

    以下简单的版本控制脚本旨在查找给定文件的最后版本号 递增它 使用新创建的文件 例如编辑器 运行给定命令 然后将其保存到稳定版本 由于它很简单 因此不会检查任何内容 因为脚本会根据需要进行修改 例如 如果结果不稳定 用户可以省略最后一个参数
  • Java中有秒表吗?

    Java中有秒表吗 在 Google 上我只找到了不起作用的秒表代码 它们总是返回 0 毫秒 我发现这段代码不起作用 我不明白为什么 public class StopWatch private long startTime 0 priva
  • 在 VB 中从 SQL 检索数据(第 2 部分)

    我正在尝试通过 sql 从数据库检索数据来填充列表框 我之前已经问过这个问题 但我使用的是不同的配置 而我现在使用的配置没有给出任何结果 从 SQL 中检索 VB 中的数据 那是我的旧帖子 我现在将提供我的尝试的新版本的代码 Imports
  • 对 LinqDataSource 使用通配符

    我目前在 ASP NET 页面上有一个 LinqDataSource 用作 FormView 的数据源 我需要动态改变where基于通过查询字符串传递的参数的子句 除了我希望最终用户能够使用通配符之外 我的工作正常 A 用于表示单个字符 代
  • Eclipse RCP 中的全局变量

    我该如何解决这个问题 我的主 RCP 插件中有用户凭据信息 所有其他插件也应该具有该信息 偏好存储是不可能的 因为偏好存储还需要一个全局可用的节点名 有没有可能实现全局变量 Thanks 有几种选择 快速而肮脏的方法是将全局变量的 gett
  • 如何在PageObjectModel中的PageFactory中添加显式等待?

    我已经添加了硬编码等待thread sleep 在我下面的代码中 如何使用显式等待 我想等到 用户名 WebElement 出现 我的程序运行完美 我已经写好了测试用例 package com pol zoho PageObjects im
  • C# 中 VB.NET 类型转换函数 (CBool​​) 的替代方案?

    有没有什么可以替代VB的CBoolC 中的关键字 那么其他所有功能呢 CBool将转换为布尔值任何有效的布尔值 0 False null etc 诀窍是CxxVB NET 中的 函数 实际上并不是函数 事实上 他们更像是运营商编译器将其转换
  • WooCommerce:从产品变体中获取自定义字段并将其显示为变体价格的后缀

    我试图从产品变体的自定义数字字段中获取值 并将其显示为变体价格的后缀以及自定义文本 我的工作时间是从 WooCommerce 从产品变体中获取自定义字段并将其显示在 附加信息区域 将自定义文本添加到 Woocommerce 中的变化价格 这
  • 文件系统 API:文件和文件夹位于何处

    我目前正在开发一个 Chrome 应用程序 需要访问本地文件和目录 我的问题是当我创建文件或文件夹时它们位于哪里 该扩展当前位于我的主目录中 并且创建的文件不在扩展目录中 文件系统 API 是 虚拟的 因为您无法将文件完全按字面意思存储在客
  • 如何在 MATLAB 中绘制 4D 轮廓线 (XYZ-V)?

    我有 XYZ 数据集作为坐标 V 作为每个点的值 100x4 矩阵 我使用 patch 绘制 3D 曲面 按面和顶点 如何在 3D 表面上绘制 V 而非 Z 的轮廓线 Contour3 函数绘制 Z 的 3D 轮廓线 但我需要 V 的轮廓线
  • 如何在我的 SupportFragment 中添加 YouTube 播放器?

    我的 XML 代码
  • 从 .sql 文件顺序调用存储过程

    我被困在这里了 我有一个程序 我想连续运行 X 次 X 是几千次 基于输入数据的过程执行以下操作 1 查找 actions id 如果没有找到LEAVEs 2 查找users id 如果没有找到 则创建一个并使用LAST INSERT ID