Sql 将行插入Oracle数据库而不获取重复密钥错误

Sql 将行插入Oracle数据库而不获取重复密钥错误,sql,oracle,Sql,Oracle,为了根据匹配条件插入多行,我编写了以下脚本: Insert Into RATE_HEADER_NEGOTIATED (RESORT, RATE_CODE, NAME_ID, BEGIN_DATE, END_DATE, INSERT_USER, INSERT_DATE, UPDATE_USER, UPDATE_DATE, ORDER_BY) (SELECT 'HRHLC','ST20B',NAME_ID,'01-JAN-2016','12-FEB-2016', '327','12-FEB

为了根据匹配条件插入多行,我编写了以下脚本:

Insert
Into RATE_HEADER_NEGOTIATED (RESORT, RATE_CODE, NAME_ID, BEGIN_DATE, END_DATE,
  INSERT_USER, INSERT_DATE, UPDATE_USER, UPDATE_DATE, ORDER_BY)
(SELECT 'HRHLC','ST20B',NAME_ID,'01-JAN-2016','12-FEB-2016',
   '327','12-FEB-2016','327','12-FEB-2016','1'
from rate_header_negotiated
where resort = 'HRHLC'
and RATE_CODE = 'ST20BL'
and RATE_CODE <> 'ST20B'
and END_DATE >= '01-JAN-16');

我的问题是它给了我重复的键错误,因为已经有包含“ST20B”的行了。我需要修复脚本的该部分,这样它只会在不包含该ST20B的行上插入行。如果在运行脚本之前手动删除重复的行,那么脚本可以工作。

如果第一个条件为真,第二个也必须是,所以它是多余的:

and RATE_CODE = 'ST20BL'
and RATE_CODE <> 'ST20B'
你也可以做一个左连接,或者不在,但不存在,我认为这很容易理解

在Oracle 11gR2中,您可以不检查密钥是否存在。您可能更愿意这样做,或者更愿意明确表示您期望并希望避免现有记录。也可以记录错误,但这里似乎不需要


我还改为使用日期文字,这样您就不必依赖隐式转换或会话NLS设置,并删除了数字周围看似不正确的单引号,前提是这些表中的列都是数字类型,从而避免了进一步的隐式转换。

主键是什么?请显示表定义和所有唯一约束。不要依赖NLS设置和隐式日期转换;用于指定日期“2016年1月1日”、“DD-MON-YYYY”或类似日期“2016-01-01”的日期文字。您似乎还将数字作为字符串传递。表的主键/唯一键是什么?主键是NAME\u ID列,它是每个配置文件的标识符。所以基本上我想得到包含ST20BL的配置文件,并复制该行,但插入ST20B。但是有些名字的确有ST20B,这是全部的钥匙?您的插入使用的是选定的名称\u id,因此,如果删除这些名称,它将找不到或插入任何内容。您确定姓名和费率代码上都没有吗?抱歉,如果您这样说的话,是的。如果我不在度假区、费率代码和姓名代码中输入,则不会输入任何内容。如果我去删除导致重复的配置文件,上面的代码工作得非常好嗨Alex,非常感谢你的上述内容,我确实尝试了一下,但仍然排除了以下错误:错误报告:SQL错误:ORA-00001:unique constraint OPERA.RATE_HEADER_NEG_UK违反了00001。00000-违反了唯一约束%s.%s*原因:UPDATE或INSERT语句试图插入重复的密钥。对于在DBMS MAC模式下配置的受信任Oracle,如果在不同级别存在重复条目,则可能会看到此消息*措施:删除唯一限制或不插入密钥。RATE_HEADER_NEG_UK是度假酒店的密钥,RATE_代码,NAME_ID?为表及其所有键/索引添加DDL会很有帮助。反正没有一个表叫DDL,所以我不确定错误是从哪里来的。我在提取方面比插入Rate_HEADER_NEG_UK更训练有素,UK是约束名,而不是表名;从英国部分来看,这可能是一个独特的约束,而不是主键。查看所有列以查看哪些列被覆盖。或者使用dbms_metadata.get_ddl获取表创建语句和约束/索引创建语句。
insert into RATE_HEADER_NEGOTIATED (RESORT, RATE_CODE, NAME_ID, BEGIN_DATE,
  END_DATE,INSERT_USER, INSERT_DATE, UPDATE_USER, UPDATE_DATE, ORDER_BY)
select 'HRHLC', 'ST20B', NAME_ID, DATE '2016-01-01',
  DATE '2016-02-12', 327, DATE '2016-02-12', 327, DATE '2016-02-12', 1
from rate_header_negotiated rhn
where RESORT = 'HRHLC'
and RATE_CODE = 'ST20BL'
and END_DATE >= DATE '2016-01-01'
and not exists (
  select null
  from rate_header_negotiated
  where RESORT = rhn.RESORT
  and NAME_ID = rhn.NAME_ID
  and RATE_CODE = 'ST20B'
  -- any other key columns
);