我正在尝试运行查询:

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;


外键是与产品表(ProductId)的标识关系

本质上,我想完成的是:
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/

10-11 03:10