SQL-假脱机插入

时间:2018-12-04 16:31:15

标签: sql oracle spool insert-statement

我正在创建插入语句来填充我的表。当我测试它们时,它们运行良好,但是,当我开始假脱机使用以前工作的相同代码时,突然给我一个错误(ORA-00001:违反唯一约束)。在研究问题时,似乎在尝试向表中输入重复信息时就出现了问题。但是,我总是清除序列并在假脱机之前重新输入它们,所以这没有意义。这是我要运行的示例,正​​如我所说的,否则代码可以正常运行:

SQL> INSERT INTO bill_tos_sr
2 (
3 bill_to_no,
4 bill_to_name,
5 bill_to_street,
6 bill_to_city,
7 bill_to_state,
8 bill_to_zip,
9 bill_to_phone  
10 )
11 VALUES
12 (bill_tos_seq.NEXTVAL,
13 'Walmart',
14 '1000 Indiantown St',
15 'Ft Lauderdale',
16 'FL',
17 '33401',
18 '9438476698'
19 );
INSERT INTO bill_tos_sr
*
ERROR at line 1:
ORA-00001: unique constraint (MONPM16.BILL_TO_NO_PK) violated

2 个答案:

答案 0 :(得分:1)

重置序列(在这种情况下为删除和重新创建)对表中已经存在的数据没有影响。除了通过代码,序列和表之间没有真正的关系。 (例如,您可以在多个表中使用相同的序列)。如果您在12c +中使用了身份列,那将是不正确的;但是您不在您的示例中。

所以实际上您要做的是:

create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
drop sequence bill_tos_seq;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);

除非另行指定,否则序列的两个版本都将从1开始,这意味着您的两个插入都将尝试创建bill_to_no设置为1的行-这违反了约束。

在尝试重新插入数据之前,需要从表中删除数据。如果开始时是空的,则可以执行简单的截断或删除操作(当然要小心!)。

create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
drop sequence bill_tos_seq;
truncate table bill_tos_sr;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);

如果在开始之前它已经有一些数据,那么您需要确定第一次插入哪些行,然后仅删除这些行。

您还可以通过回滚测试并重新运行它:

create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);
rollback;
drop sequence bill_tos_seq;
create sequence bill_tos_seq;
insert into bill_tos_sr (bill_to_no, ...) values (bill_tos_seq.nextval, ...);

请注意,如果这样做,则必须在序列的放置/创建之前 ,因为DDL是隐式提交的。因此事后回滚将无效。

您可能回滚了错误的点,或者根本没有回滚并且没有意识到数据是由于其他原因提交的-也许您退出了SQL * Plus却没有意识到默认也会提交。提交数据后,您必须先删除它,然后才能重新插入它,否则您将继续遇到约束冲突。

但是,这与假脱机输出无关。

答案 1 :(得分:0)

我假设BILL_TO_NO_PK是列BILL_TO_NO的PK /唯一约束。

插入时,您正在从序列bill_tos_seq.NEXTVAL中提供新值。似乎重新启动了该序列,或者已在表中手动输入了数据。

在任何情况下,序列值都会与表中的现有数据冲突。

解决方案?我会找到该列的最大值,然后将序列值设置为比该值大一。