Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql:使用INSERT SELECT中的自动增量ID进行后续插入 短版_Mysql_Select_Insert_Auto Increment - Fatal编程技术网

Mysql:使用INSERT SELECT中的自动增量ID进行后续插入 短版

Mysql:使用INSERT SELECT中的自动增量ID进行后续插入 短版,mysql,select,insert,auto-increment,Mysql,Select,Insert,Auto Increment,有人能举个例子吗?有3个SQL表。使用插入。。。选择,从表1中获取数据并将其插入表2中。然后,使用刚刚插入的每个表2行的自动增量id将行插入表3中。。。SELECT语句 插入。。。SELECT创建多行,但无法从中获取自动增量ID,以便在后续INSERT语句中使用 扩展版 我正在寻找一种有效的方法来使用从插入创建的自动增量ID。。。在第二次插入中选择 想象一下仓库中的这种情况 仓库从供应商处接收货物托盘。托盘包含多个单独的项目,必须发送给不同的客户。托盘已登记、分解和检查。然后将每个项目分配给正确

有人能举个例子吗?有3个SQL表。使用插入。。。选择,从表1中获取数据并将其插入表2中。然后,使用刚刚插入的每个表2行的自动增量id将行插入表3中。。。SELECT语句

插入。。。SELECT创建多行,但无法从中获取自动增量ID,以便在后续INSERT语句中使用

扩展版 我正在寻找一种有效的方法来使用从插入创建的自动增量ID。。。在第二次插入中选择

想象一下仓库中的这种情况

仓库从供应商处接收货物托盘。托盘包含多个单独的项目,必须发送给不同的客户。托盘已登记、分解和检查。然后将每个项目分配给正确的客户,并标记为“就绪”。在这一点上,每个项目都会按照每个客户记录的发货状态进行发货。每个客户的帐户余额都会根据项目减少一个给定的值

问题是将帐户缩减与项目分派相关联。共有3个表格:

GoodsIn:记录来自供应商的托盘到货

CREATE TABLE GoodsIn ('InID' 'CustomerID', 'ItemSKU_ID', 'HasBeenChecked')
GoodsOut:记录发送给客户的SKU

CREATE TABLE GoodsOut ('OutID', 'CustomerID', 'ItemSKU_ID', 'DateDispatched')
账户:记录每个客户交易/余额

CREATE TABLE Ledger ('LedgerID', 'BalanceClose', 'AdjustmentAmount',  'CustomerID', 'ActionID')
(我已经大大简化了这一点——请接受GoodsIn和GoodsOut不能合并)

当SKU标记为准备发货时,我可以使用以下命令自动更新分类账余额,为每个客户提取最后一行余额并进行更新

INSERT INTO Ledger (BalanceClose, AdjustmentAmount, CustomerID) 
SELECT Ledger.BalanceClose + 
    (SELECT @Price:=ItemSKUData.ItemPrice FROM ItemSKUData WHERE ItemSKUData.ItemSKU_ID = GoodsIn.ItemSKU_ID)  AS NEWBALANCECLOSE,
    @Price AS ADJUSTMENTAMOUNT,
    Ledger.CustomerID
FROM Ledger
INNER JOIN GoodsIn ON GoodsIn.CustomerID = Ledger.CustomerID
WHERE GoodsIn.HasBeenChecked = TRUE
    AND Ledger.LedgerID IN (SELECT MAX(Ledger.LedgerID) FROM Ledger GROUP BY Ledger.CustomerID)
这一切都非常好——我得到了一个新的分类账行,其中GoodsIn.hasbeencheched=TRUE的每一行GoodsIn都有更新的BalanceClose。这些分类账行中的每一行在插入时都会获得一个自动递增的Ledger.LedgerID

然后,我可以执行几乎相同的代码来插入GoodsOut表。与分类账一样,GoodsOut.OutID也是一个自动递增的ID

我现在需要将这些分类账行(Ledger.ActionID)链接到GoodsOut.OutID。这就是Ledger.ActionID的用途-它需要映射到每个GoodsOut.OutID,以便将分类账余额的减少与向客户发送货物的操作相关联

理论上,如果这是一次插入,而不是一次插入选择,我只需将GoodsOut.LAST_INSERT_ID()用于插入分类账

但是因为我在使用插入。。。选择,我无法获取每行的自动增量ID

我能看到的唯一方法是在GoodsOut表中使用一个伪列,并在其中存储GoodsIn.ini。然后我可以使用插入中的WHERE获取GoodsOut.OutID。。。为分类账选择一个

但感觉不太优雅和安全


这就是我的问题。当表A和表B中的所有行都使用INSERT创建时,我需要使用表B的自动增量ID将表A链接到表B。。。选择。

你说得对,当你执行
INSERT…为批量插入选择
,你不容易访问自动增量id。
LAST\u INSERT\u id()
只返回生成的第一个id

大容量插入的一个有文档记录的行为是,生成的id保证是连续的,因为大容量插入将表锁定到语句末尾

说:

  • innodb_autoinc_锁定模式=1(“连续”锁定模式)

    这是默认的锁定模式。在此模式下,“批量插入”使用特殊的AUTO-INC表级锁,并将其保持到语句结束。这适用于所有
    INSERT。。。选择
    替换。。。选择
    ,然后选择
加载数据
语句。一次只能执行一条持有AUTO-INC锁的语句

这意味着,如果您知道生成的第一个值、插入的行数(您应该能够从中获得)以及插入的行的顺序,那么您就可以可靠地知道生成的所有id


例如,MySQL JDBC驱动程序依赖于此。在执行大容量插入时,生成的id的完整列表不会返回给客户端(即JDBC驱动程序),但驱动程序有一个Java方法来返回完整列表。这是通过Java代码推断值并假设它们是连续的来实现的。

谢谢Bill,这很有意义。该方法将为生成的自动ID提供一个最小值和最大值,但它不允许我唯一地标识表2中的每一行,从而将(外键)映射到表3

假设一个客户在表1(GoodsIn)中有2个SKU订单。两者都将被添加到表2(GoodsOut),表3(分类账)将被递减。但是,使用此方法无法知道GoodsOut中的哪一行映射到分类账中的行,因为我们只有由INSERT…SELECT添加的自动ID的最小-最大范围

在我看来,我真正想要的(现在我意识到它不可能存在)是一个函数,它返回一个自动ID数组,加上SELECT…INSERT后给定列中的值

令人沮丧的是,这在PHP中非常简单,但我不想将所有DB数据加载到PHP中,转换,然后再写回,因为与直接将其实现到DB查询中相比,性能成本是巨大的

我决定坚持目前的做法——使用包含table1.id的临时列table2.temp\u table1\u id。然后,我可以对表3进行另一次插入更新,连接表1和表2,并根据需要检索表2数据

我有点希望有一个优雅的方式来做到这一点,没有额外的步骤,但似乎不是。我认为我目前的解决方案目前的重复和重复最少


有兴趣听取任何其他建议/方法。

请看,我在顶部添加了一个摘要,但我看不出如何做