【问题标题】:Referential integrity error when using infile, but no error when using mysql CLI使用 infile 时引用完整性错误,但使用 mysql CLI 时没有错误
【发布时间】:2023-03-26 16:04:01
【问题描述】:

当我尝试使用 --local-infile 选项加载 CSV 数据文件时,我收到以下错误:

第 2 行出现错误 1452 (23000):无法添加或更新子行:外键约束失败 (realtax.city_desc, CONSTRAINT city_desc_ibfk_1 FOREIGN KEY (cityid) REFERENCES city ( id) 更新级联删除级联)

错误发生在 CSV 文件的第一行(即,根本没有加载任何行)。

这里是实际的mysql加载命令:

load data LOCAL infile 'out/desc.in' into table city_desc fields terminated by ',' lines terminated by '\n';

这是 CSV 文件的第一行:

# head -1 out/desc.in
NULL,1000,"R4","B1","NWC125","SUNRISE ACRES #1 W 120 FT OF S 75",0.207

但是,当我使用 mysql CLI 时,我可以毫无问题地加载第一行。结果如下:

mysql> 插入 city_desc 值 (NULL,1000,"R4","B1","NWC125","SUNRISE ACRES #1 W 120 FT OF S 75",0.207);
查询正常,1 行受影响(0.04 秒)

这是它所引用的表数据行:

mysql> select * from city limit 1;
+------+---------+-----------------+
|编号 |道具ID | pidn |
+------+---------+-----------------+
| 1000 | 10208 | S912999001L0800 |
+------+---------+-----------------+
一组中的 1 行(0.00 秒)

以下是每个表的 SQL 定义:

create table if not exists city 
(
    id              INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    prop_id         int,
    pidn            varchar(100)
) AUTO_INCREMENT=1000, engine=innodb;

create table if not exists city_desc
(
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    cityid          int not null,
    zoning          varchar(20), 
    state_cd        varchar(20), 
    map_id          varchar(20), 
    legal_desc      varchar(100), 
    legal_acres     numeric(5,5),
    foreign key (cityid) references city(id)
    on update cascade on delete cascade
) AUTO_INCREMENT=500000, engine=innodb;

create index propid_city on city(prop_id);
create index pidn_city on city(pidn);

我阅读了其他关于关闭引用检查的线程:

SET foreign_key_checks = 0;

但我不想破解修复程序,而是想知道手动工作但不能使用 --local-infile 选项的原因。外部引用存在(记录 id 1000),为什么它不起作用?

更新:这是我在插入失败后立即运行 SHOW ENGINE INNODB STATUS 后收到的信息:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
121212 13:50:55 Transaction:
TRANSACTION 0 901853, ACTIVE 0 sec, process no 3217, OS thread id 140224990570240 inserting, thread declared inside InnoDB 492
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1216, 9 row lock(s), undo log entries 9
MySQL thread id 15389, query id 1442612 localhost root
load data LOCAL infile 'out/desc.in' into table city_desc fields terminated by ',' lines terminated by '\n'
Foreign key constraint fails for table `realtax`.`city_desc`:
,
  CONSTRAINT `city_desc_ibfk_1` FOREIGN KEY (`cityid`) REFERENCES `city` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index `cityid` tuple:
DATA TUPLE: 2 fields;
 0: len 4; hex 80000000; asc     ;; 1: len 4; hex 800ea15e; asc    ^;;

But in parent table `realtax`.`city`, in index `PRIMARY`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 800003e8; asc     ;; 1: len 6; hex 00000007aed1; asc       ;; 2: len 7; hex 800000002d0110; asc     -  ;; 3: len 4; hex 800027e0; asc   ' ;; 4: len 15; hex 533931323939393030314c30383030; asc S912999001L0800;;

【问题讨论】:

  • csv 文件有多少行?引用问题是否可能存在于另一行?
  • 但这不是意味着要插入一些行吗?事实并非如此。
  • 取决于是否使用事务;在交易中,要么全部要么没有。
  • 没有正在使用的事务——根据我包含的 SQL 定义,我正在将记录直接插入到表中。

标签: mysql foreign-keys referential-integrity


【解决方案1】:

你需要跳过CSV文件的第一行,添加IGNORE number LINES选项。

load data LOCAL infile 'out/desc.in'
into table city_desc
fields terminated by ','
lines terminated by '\n'
ignore 1 lines;

【讨论】:

  • 感谢您的回复,但这不是一个好的解决方案。这条线本身不是问题,因为 1)它手动工作 2)我尝试了你的建议,但仍然失败。
  • 如果我没有选择数据库,或者选择了错误的数据库,mysql会以错误的形式告诉我。
  • LOAD DATA 之后运行SHOW ENGINE INNODB STATUS。它将显示有关错误的详细信息。
  • 请查看我最初评论的更新。我运行了 SHOW ENGINE INNODB STATUS 命令并发布了结果。
【解决方案2】:

根据您提供的信息,该行不应该造成任何问题。因此,快速提问:csv 中有多少行?如果多于 1 行,其中是否至少有一个包含不在主键中的外键值?
如果该行确实包含数据数据,则该错误肯定不在该行上;它在不同的行上。

【讨论】:

  • CSV 文件包含近 400,000 行。你说错误可能在另一行。在此之后,我创建了一个仅包含第一行数据的 infile。我尝试使用 infile 命令加载它,它成功了!这告诉我你是对的。然后我打开 CSV 文件并仔细检查数据。事实上,有一行外键设置为零,这是无效的。
  • 我修复了我的脚本以识别空列,这导致了这一系列事件。通过不检查每次插入的自动增量 ID,我将该错误传递给 infiles。加载准备脚本将每一行一个接一个地加载到第一个表(城市)中。然后,我获取该记录的自动增量 ID,并将 CSV 行写入一系列文本文件(infiles)。我的脚本试图在 city 表中插入一条带有空字段的记录,结果卡住了。当我检索到自动增量 ID 时,它返回一个零。我没有绕过,而是将它传递给了 infiles。
  • 很好;我很高兴你解决了它;您可能需要选择其中一个答案作为所选答案;它会给你更多的积分,并允许其他人在未来帮助你。
猜你喜欢
  • 2017-09-10
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
相关资源
最近更新 更多