我正在尝试运行查询:
INSERT
INTO `ProductState` (`ProductId`, `ChangedOn`, `State`)
SELECT t.`ProductId`, t.`ProcessedOn`, \'Activated\'
FROM `tmpImport` t
LEFT JOIN `Product` p
ON t.`ProductId` = p.`Id`
WHERE p.`Id` IS NULL
ON DUPLICATE KEY UPDATE
`ChangedOn` = VALUES(`ChangedOn`)
(我不太确定查询是否正确,但是它似乎正在工作),但是我遇到了以下问题。在创建“产品”表中的条目之前,我正在运行此查询,并且由于该条目尚未在“产品”表中而导致出现外键约束问题。
我的问题是,有没有一种方法可以运行此查询,但是要等到下一个查询(更新Product表)之后再执行上面查询的插入部分?还要注意,如果查询在创建Product条目之后运行,它将不再看到p。
Id
为空,因此失败,因此必须在创建Product条目之前执行该查询。--->编辑我试图实现的概念如下:
首先,我要将一组数据导入到临时表中,
Product
表是通过临时表中的数据集添加的(或过去使用过的)所有产品的列表。我需要一个单独的表,该表为产品提供状态更改,因为有时产品将变得不可用(不再出现在供应商提供的数据集中)。ProductState表如下:
CREATE TABLE IF NOT EXISTS `ProductState` (
`ProductId` VARCHAR(32) NOT NULL ,
`ChangedOn` DATE NOT NULL ,
`State` ENUM('Activated','Deactivated') NULL ,
PRIMARY KEY (`ProductId`, `ChangedOn`) ,
INDEX `fk_ProductState_Product` (`ProductId` ASC) ,
CONSTRAINT `fk_ProductState_Product`
FOREIGN KEY (`ProductId` )
REFERENCES `Product` (`Id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
外键是与产品表(
Product
。Id
)的标识关系本质上,我想完成的是:
1.每当供应商数据集中出现新产品(或先前已停用的产品)时,该记录就会在ProductState表中创建为“已激活”。
2.每当产品(已激活)未出现在供应商数据集中时,该记录就会在ProductState表中创建为“已停用”。
ProductState表的目的是跟踪产品的激活和停用状态。另外,ProductState与产品表是多对一关系,并且产品的状态每天只会更改一次,因此我的PKEY将为ProductId和ChangedDate。
最佳答案
使用外键,您肯定需要先在Product表上存储数据,然后再进入状态,请考虑以下逻辑:“不存在的东西如何具有状态”?
所以你应该做什么的伪代码:
阅读供应商的产品列表
将它们与“产品”表中的现有列表进行比较
如果找到新的:3.1将其插入到Product表中,3.2将其插入到ProductState表中
如果缺少供应商列表:4.1将其插入到ProductState表中
所有这些都应在一次交易中完成。请注意,除非您确实想删除与其关联的所有信息,否则不要从Product表中删除内容。还删除您已存储的所有“状态”。
与其尝试在1个查询中完成所有操作,不如说是最好的选择,就是创建一个存储过程来按上面的步骤进行工作。我认为在1个查询中进行所有操作变得过于复杂(或者在这种情况下,可能是不可能的)。
编辑:像这样:
CREATE PROCEDURE `some_procedure_name` ()
BEGIN
-- Breakdown the tmpImport table to 2 tables: new and removed
SELECT * INTO _temp_new_products
FROM`tmpImport` t
LEFT JOIN `Product` p
ON t.`ProductId` = p.`Id`
WHERE p.`Id` IS NULL
SELECT * INTO _temp_removed_products
FROM `Product` p
LEFT JOIN `tmpImport` t
ON t.`ProductId` = p.`Id`
WHERE t.`ProductId` IS NULL
-- For each entry in _temp_new_products:
-- 1. Insert into Product table
-- 2. Insert into ProductState table 'activated'
-- For each entry in _temp_removed_products:
-- 1. Insert into ProductState table 'deactivated'
-- drop the temporary tables
DROP TABLE _temp_new_products
DROP TABLE _temp_removed_products
END
关于mysql - 由于外键限制,插入延迟,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5967572/