【问题标题】:MySQL and PHP. Should the code below be a MySQL Routine or PHP function?MySQL 和 PHP。下面的代码应该是 MySQL 例程还是 PHP 函数?
【发布时间】:2014-02-26 01:54:23
【问题描述】:

我正在做一个 LAMP 项目。这不是给客户的。这只是一个学习经验。该项目模拟了一个仓库,该仓库在订单的放置、组装和运输过程中对其进行跟踪。当一个订单的所有物品都组装好后,我希望该订单自动将其状态更新为“准备发货”。

我不知道是否可以在 MySQL 例程中编写此逻辑,或者是否应该将其编写在 PHP 代码中。

我将重点关注两个关键表:sale 和 sale_detail。

Sale 有两个重要的列:id 和 stage。 Id 是客户订单号。它是唯一的、主键和自动递增的。 Stage 是订单经历的阶段:0(进行中)、1(从仓库取货)、2(准备发货)和 3(已发货)。

Sale_detail 包含每次销售的商品列表。它包含三列:order_id、item_id 和 status。 order_id 是 sale 中 id 列的外键。 Item_id 是订单中每件商品的 SKU。此表中的状态为二进制:0 表示尚未从仓库中检索到。 1 表示有。

以下是一些示例数据:

Sale
id…..stage
10…..3
11…..3
12…..1
13…..1
14…..2

Sale_detail
order_id….item_id….status
10….43…1
10….45…1
10….42…1
11….42…1
12….45…0
12….43…1
13….44…1
13….48…1
14…42…2

在上面的示例中,订单 10 和 11 已发货(第 3 阶段)。订单 14 已准备好发货(第 2 阶段)。订单 12 和 13 正在仓库中进行检索(阶段 1)。

查看 sale_detail 表中的订单 12 和 13。订单 12 已准备就绪。一项已检索,但另一项尚未检索。订单 13 已准备好发货;它的两个项目都已从仓库中取回(状态 1)。

因此,如果订单 13 的所有项目都设置为状态 1,则其在销售表中的阶段应设置为 2。我想要一个自动执行此操作的流程。首先,它查找所有状态为 1 的销售订单。对于每个此类订单,它会在 sale_detail 中查找该订单的所有商品。如果 sale_detail 中该订单的所有行都具有阶段 1,则将阶段设置为 sale 2。

我可以使用一对嵌套的 for-each 循环来做到这一点。下面是一些混合的 SQL/Java 伪代码:

int[] stage1_orders := (SELECT id FROM sale WHERE stage = 1);
for(int id : orders){
    bool ready = false;
    int[] statuses := (SELECT status FROM sale_detail WHERE order_number = id);
        for (int status: statuses){
        if (status == 0){ready = false; break;}
        if(status == 1){ready = true;}
        }
    if (ready == true){UPDATE sale SET stage = 2 WHERE id = id;}
    }

我知道我不能在 MySQL 中执行 for-each 循环。我可以在 MySQL 中写类似的东西吗?还是我最好用另一种语言(Python、PHP 等)编写工作并让它每分钟左右运行一次?

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:
    update Sale
    set stage = 2 
    where stage = 1
    and 0 = (
      select count(*) 
      from Sale_detail
      where order_id = Sale.id
      and status <> 1 
      )
    

    把它放在一个存储过程中,当任一表被更新时触发。

    【讨论】:

    • 令人着迷。我从来没有学会在 WHERE 子句中使用常量。
    • 仅“修复”正在更新的 order_id 可能会更有效(因此更好),但我想提出一个简单的解决方案。
    • 我们如何知道括号中的部分将针对它找到的每个 sale.id 运行一次?相关:它如何加载“Sale.id”以及销售表中每一行的 id 值?
    • 记住,SQL 处理集合。所以SELECT * FROM table 是表中所有内容的集合。 WHERE stage = 1 是满足该标准的子集。子选择有它自己的集合。从 Sale_detail 中的每一行开始,但随后被“过滤”以删除 status = 1 和 order_id 与 Sale.id 匹配的行 - 但 Sale.id 取决于在 Sale 中检查的行 - 所以数据库引擎会计算出来对于 Sale 中的每一行,它都必须进行子选择(智能数据库引擎会对此进行优化并首先检查 stage = 1 谓词,因此它只在必要时进行子选择)。
    • 顺便说一句,这被称为相关子选择,因为在子选择 where 子句中两个表之间存在连接。见en.wikipedia.org/wiki/Correlated_subquery
    猜你喜欢
    • 2011-03-26
    • 1970-01-01
    • 2012-12-27
    • 1970-01-01
    • 2011-11-23
    • 2011-04-28
    • 2012-03-06
    • 2012-10-07
    • 1970-01-01
    相关资源
    最近更新 更多