我有以下SQL Fiddle描述的两个表格。我的应用程序需要在tblA
中在两个已存在的记录之间插入新记录。例如,如果tblA有6条AID
范围为0到5的记录,并且我想插入一条AID
为4的新记录,我会增加元组4的AID
和元组5一个然后插入新记录。因此,我使用以下预准备语句将AID
和tblA
的元组的列tblB
的值(通过级联)递增一:
update tblA set AID = (AID + 1) where AID >= ? order by AID desc;
在我的测试安装上,上述声明效果很好。但是,在我们的生产系统中,我们在某些情况下会收到以下错误消息:
Foreign key constraint for table 'tblA', record '4' would lead to a duplicate entry in table 'tblB'
现在,我不清楚究竟是什么导致问题以及如何解决问题。
我感谢任何提示。提前谢谢!
答案 0 :(得分:1)
关于tblB
这个
create table if not exists tblB(
BID integer not null,
AID integer not null,
constraint fkB_A foreign key(AID) references tblA(AID),
primary key(AID, BID)
);
应该是
create table if not exists tblB(
BID integer not null,
AID integer not null,
constraint fkB_A foreign key(AID) references tblA(AID)
on update cascade,
-- ^^^^^^^^^^^^^^^^
primary key(AID, BID)
);
数据和SQL数据库的关系模型中的代理ID号是没有意义的。除非你知道的不仅仅是你的问题,否则AID和BID毫无意义。在设计合理的数据库中,根本不需要根据其代理ID号在两行之间插入行。
如果您的实际需求只是在“2015-12-01 23:07:00”和“2015-12-04 14:58:00”之间插入时间戳,则不需要ID号4要做到这一点。
-- Use single quotes around timestamps.
insert into tblA values (-42, '2015-12-03 00:00:00');
select * from tblA order by RecordDate;
AID RecordDate -- 0 2015-11-07 16:55:00 1 2015-11-08 22:16:00 2 2015-11-10 14:26:00 3 2015-12-01 23:07:00 -42 2015-12-03 00:00:00 5 2015-12-04 14:58:00 6 2015-12-13 10:07:00
关于tblA
此
create table if not exists tblA(
AID integer not null,
RecordDate varchar(25),
constraint pkA primary key(AID)
);
应该是
create table if not exists tblA(
AID integer not null,
RecordDate varchar(25) not null,
-- ^^^^^^^^
constraint pkA primary key(AID)
);
如果没有not null
,您可以插入这样的数据。
AID RecordDate -- 17 Null 18 Null 19 Null
由于代理ID号码毫无意义,因此这些行基本上都是相同的,同样没用。
关于更新声明
update tblA
set AID = (AID + 1)
where AID >= 4
order by AID desc;
标准SQL在update语句中不允许order by
处于此位置。 MySQL documents this为
如果指定了ORDER BY子句,则按顺序更新行 指定的。
关系模型和SQL是面向集合的。更新应该“一下子”发生。恕我直言,你最好学习标准SQL并使用更好地支持标准SQL的dbms。 (PostgreSQL让人想起。)但是将on update cascade
添加到tblB(上面)将使你的update语句在MySQL中成功。
update tblA
set AID = (AID + 1)
where AID >= 4 order by AID desc;
答案 1 :(得分:0)
添加on update cascade
可能会解决您的问题
create table if not exists tblB(
BID integer not null,
AID integer not null,
constraint fkB_A foreign key(AID)
references tblA(AID)
on update cascade,
primary key(AID, BID));