简体   繁体   English

SQL-假脱机插入

[英]SQL - Spooling inserts

I am creating insert statements to populate my tables. 我正在创建插入语句来填充我的表。 They run fine when I test them, however, when I start to spool the same code that worked previously suddenly gives me an error (ORA-00001: unique constraint violated). 当我测试它们时,它们运行良好,但是,当我开始假脱机使用以前工作的相同代码时,突然给我一个错误(ORA-00001:违反唯一约束)。 When researching the issue it seems that the issue occurs when trying to enter duplicate information into a table. 在研究问题时,似乎在尝试向表中输入重复信息时就出现了问题。 However, I always clear the sequences and re-enter them before spooling so this wouldn't make sense. 但是,我总是清除序列并在假脱机之前重新输入它们,所以这没有意义。 Here is an example of what I'm trying to run, and as I said the code works fine otherwise: 这是我要运行的示例,正​​如我所说的,否则代码可以正常运行:

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

Resetting the sequence (dropping and recreating in this case) has no effect on data that already exists in the table. 重置序列(在这种情况下为删除和重新创建)对表中已经存在的数据没有影响。 There is no real relationship between the sequence and table, except through your code. 除了通过代码,序列和表之间没有真正的关系。 (You can use the same sequence across multiple tables, for instance). (例如,您可以在多个表中使用相同的序列)。 That wouldn't be true if you were using an identity column in 12c+; 如果您在12c +中使用了身份列,那将是不正确的; but you aren't in your example. 但您不在您的示例中。

So really what you have done is: 所以实际上您所做的是:

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, ...);

Unless you specified otherwise, both versions of the sequence will start from 1, which means both of your inserts will try to create a row with bill_to_no set to 1 - which violates the constraint. 除非另外指定,否则序列的两个版本都将从1开始,这意味着您的两个插入都将尝试创建一个将bill_to_no设置为1的行-这违反了约束。

You need to delete the data from the table before you try to reinsert it. 您需要先从表中删除数据,然后再尝试将其重新插入。 If it was empty to start with then you can do a simple truncate or delete (being careful, of course!). 如果开始时是空的,则可以执行简单的截断或删除操作(当然要小心!)。

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, ...);

If it already had some data before you started then you'll need to figure out which rows you inserted the first time and only delete those. 如果开始之前已经有一些数据,则需要确定首次插入哪些行,然后仅删除这些行。

You could also have tested and re-run this with a rollback: 您还可以通过回滚测试并重新运行它:

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, ...);

Note that if you did that it would have to be before the drop/create of the sequence, because DDL commits implicitly; 请注意,如果这样做,则必须删除/创建序列之前,因为DDL隐式提交。 so a rollback afterwards would have no effect. 因此事后回滚将无效。

It's possible you rolled back at the wrong point, or that you didn't roll back at all and didn't realise the data had been committed for some other reason - perhaps you exited SQL*Plus and didn't realise that would commit by default too. 您有可能回滚了错误的点,或者根本没有回滚,也没有意识到数据是由于其他原因提交的-也许您退出了SQL * Plus,但没有意识到也是默认值。 Once the data has been committed you have to delete it before you can reinsert it, or you'll continue to get constraint violations. 提交数据后,您必须先删除它,然后才能重新插入它,否则您将继续遇到约束冲突。

However, this has nothing to do with spooling the output. 但是,这与假脱机输出无关。

I'll assume BILL_TO_NO_PK is the PK/unique constraint of the column BILL_TO_NO . 我假设BILL_TO_NO_PK是列BILL_TO_NO的PK /唯一约束。

When inserting, you are are providing new values from the sequence bill_tos_seq.NEXTVAL . 插入时,您将从序列bill_tos_seq.NEXTVAL提供新值。 It seems the sequence was restarted, or that data was entered manually in the table. 似乎序列已重新启动,或者数据已在表中手动输入。

In any case, the sequence values are colliding with existing data in the table. 无论如何,序列值都会与表中的现有数据冲突。

Solution? 解? I would find the max value for the column, and then set the sequence value to one more than that value. 我会找到该列的最大值,然后将序列值设置为比该值大一的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM