【问题标题】:SQLSTATE General Error 1005 Can't create table '#sql-3d63_ca5dc9' (errno: 150)SQLSTATE 一般错误 1005 无法创建表 '#sql-3d63_ca5dc9' (errno: 150)
【发布时间】:2017-08-20 06:48:17
【问题描述】:

我有一个使用 Doctrine 的 Symfony CRM 项目,我目前正在转移到新服务器,CRM 连接到 OpenCart 2。

我的一些表具有外键,允许我从项目中的定制表中引用一些 OpenCart 表,例如产品表的产品 ID 和客户表的客户 ID 等。

但是,当我尝试运行 doctrine:schema:update --force 时,出现以下错误:

执行 'ALTER TABLE project ADD 时发生异常 约束 FK_2FB3D0EE4584665A 外键(product_id)参考 oc73_product (product_id)':

SQLSTATE[HY000]:一般错误:1005 无法创建表 'oc2017_myshop.#sql-3d63_ca5dc9'(错误号:150)

引发此错误的两个语句如下:

ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EE4584665A FOREIGN KEY (product_id) REFERENCES oc73_product (product_id);
ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEB18AFA7E FOREIGN KEY (stageName) REFERENCES stage (id);

我不太明白上述错误是什么意思,因为我没有创建一个名为 sql-3d63_ca5dc9 的表?任何人都可以对此有所了解吗?

如果需要更多信息来帮助解决此问题,请告诉我,我将包括在内。

【问题讨论】:

  • #开头的表名是临时表。
  • 为什么要尝试创建临时表?又怎么做不到呢?

标签: mysql symfony doctrine


【解决方案1】:

错误消息告诉我们外键约束的格式不正确。

外键列和被引用列的数据类型不匹配。

或者在被引用的表上没有定义以被引用列作为前导列的索引。

或者project 表中的行与引用表中的行不匹配。也就是说,product_id 列包含未出现在 oc73_product 表中的值。

错误消息没有区分这些可能性;它只是告诉我们外键有问题。


表名#sql-3d63_ca5dc 是一个中间名。 MySQL 将在 ALTER TABLE 运行时创建表的工作副本,然后将现有表的名称交换到新副本上。


为了调试这个,

比较projectoc73_productproduct_id列的数据类型

SHOW CREATE TABLE project ;
SHOW CREATE TABLE oc73_product ;

数据类型必须是精确匹配。

验证oc73_product 有一个以product_id 为前导列的KEY。这可以是 PRIMARY KEY、UNIQUE KEY,或者我认为 MySQL 甚至可以让你只用一个 KEY。

验证project 中没有违反约束的行。如果此查询返回任何行,则存在违反外键约束的行:

SELECT j.product_id
  FROM project j
  LEFT
  JOIN oc73_product d
    ON d.product_id = j.product_id
 WHERE d.product_id IS NULL

使用反连接模式的查询结果(上图)等价于:

SELECT j.product_id
  FROM project j
 WHERE NOT EXISTS ( SELECT 1
                      FROM oc73_product d
                     WHERE d.product_id = j.product_id
                  )

跟进

正如@Shadow 在评论中提到的,SHOW ENGINE INNODB STATUS 的输出可能包含这样的部分:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2017-03-27 14:14:14 7fce73f9d700 Error in foreign key constraint creation
  for table `db`.`table_name`.

包含有关遇到的错误情况的详细信息。 InnoDB 引擎对错误的了解比他告诉 MySQL 的要多。 MySQL 只是报告“InnoDB 报告错误 150”,没有任何详细说明为什么 InnoDB 报告该错误。

【讨论】:

  • 您可以提到,您可以使用SHOW ENGINE INNODB STATUS 语句获取错误的详细描述
  • 所有索引似乎都已到位 - 它以前在以前的服务器上工作过,但看起来只是在它试图映射到新的 OpenCart 表时。当我运行 SHOW ENGINE INNODB STATUS 时,它只是说 Permission Denied....
  • MySQL 用户需要被授予PROCESS 权限才能执行SHOW ENGINE INNODB STATUS。 (我们在这里假设表projectoc73_product 都是InnoDB 表,即SHOW CREATE TABLE 显示ENGINE=InnoDB。)
  • 我相信他们都是 InnoDB。当我运行 SHOW CREATE TABLE 命令时,它会截断响应,因此我实际上看不到完整结果
  • 我们可以从 information_schema.tables 获取表信息,例如“SELECT table_schema, table_name, table_type, engine from information_schema.tables where table_name in ('oc73_product','project')”。我们可以从 information_schema.columns 中获取列信息,从 information_schema.key_column_usage 中获取索引信息。 (此外,我们需要修复从 SHOW CREATE TABLE 截断结果的任何“它”。或者,我们可以使用 mysql 命令行客户端。从 SHOW CREATE TABLE 截断返回不应该是一个问题。)跨度>
猜你喜欢
  • 2016-12-02
  • 2020-12-02
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2017-04-09
  • 2016-10-12
  • 1970-01-01
相关资源
最近更新 更多