当前位置: 首页 > 知识库问答 >
问题:

ORA-00001:违反了唯一约束(MYUSER.ADI\u PK)

伏星汉
2023-03-14

我有两张表,adv\u institution和institution<代码>机构有5000行,而高级机构有1400行

我想使用Oracle MERGE将记录从机构回填到高级机构。这两个表有大约四个常用字段,我可以用它们来填充。

这是我全部的合并声明

merge into
  adv_institution to_t
using (
  select
    uni.*,
    adv_c.country_cd as con_code_text
  from
    (
      select 
        institution_cd, 
        name,
        institution_status,
        country_cd
      from 
        institution uni
      where
        uni.institution_status = 'ACTIVE' and
        uni.country_cd is not null
      group by
        institution_cd,
        name,
        institution_status,
        country_cd
      order by
        name  
    ) uni,
    country_cd c_cd,
    adv_country adv_c
  where
    uni.country_cd = c_cd.country_cd and
    c_cd.description = adv_c.country_cd
) from_t
on
(
  to_t.VENDOR_INSTITUTION_CD = from_t.INSTITUTION_CD or
  to_t.INSTITUTION_CD = from_t.NAME
)
WHEN NOT MATCHED THEN INSERT (
  to_t.INSTITUTION_CD,
  to_t.INSTITUTION_NAME,
  to_t.SHORT_NAME,
  to_t.COUNTRY_CD,

  to_t.NOTE,
  to_t.UNIT_TERMINOLOGY,
  to_t.COURSE_TERMINOLOGY,
  to_t.CLOSED_IND,

  to_t.UPDATE_WHO,
  to_t.UPDATE_ON,
  to_t.CALLISTA_INSTITUTION_CD
)
VALUES (
  from_t.NAME,
  from_t.NAME,
  '',
  from_t.con_code_text,

  '',
  'UNIT',
  'COURSE',
  'N',

  'MYUSER',
  SYSDATE,
  from_t.institution_cd
);

我的错误是

错误报告-ORA-00001:违反了唯一约束(MYUSER.ADI\u PK)

ADI\U PK是指adv\U机构。institution\u cd是主键,必须唯一。

这是因为在WHEN Not MATCHED THEN INSERT中有一个插入语句。我将from_t. NAME插入到to_t.INSTITUTION_CD中。

在插入到to\t.INSTITUTION\u CD

但我做了一个组声明,以确保from\t的名称是唯一的:

(
      select 
        institution_cd, 
        name,
        institution_status,
        country_cd
      from 
        institution uni
      where
        uni.institution_status = 'ACTIVE' and
        uni.country_cd is not null
      group by
        institution_cd,
        name,
        institution_status,
        country_cd
      order by
        name  
    ) uni

我不确定我是否正确理解了这个问题。我尽了我所能,但仍然没有运气。

共有2个答案

柏明亮
2023-03-14

“但我做了一个组声明,以确保from\u t.NAME是唯一的:”

但是您的查询不会这样做。它会生成一组不同的(institution_cd、name、institution_status、country_cd)组合。显然,这样的集合可能包含多个name的重复,每个country_cd的不同值都有一个重复。由于您的键中有四个元素,您实际上保证了您的集合将多次出现name

将其与ON条件中的或复合,这意味着如果to\u t.VENDOR\u INSTITUTION\u CD=from\u t.INSTITUTION\u CD,即使目标表中已经有一条记录,其中to\u t.INSTITUTION\u CD=from\u t.NAME,也会触发不匹配的逻辑。

问题是MERGE语句是原子的。来自USING子查询的记录集必须包含唯一键。当Oracle在结果集中再次发现相同的名称时,它不会说,我已经合并了其中一个,让我们跳过它。它必须抛出ORA-00001,因为Oracle无法知道应用了哪个记录,哪个组合(institution\u cd、name、institution\u status、country\u cd)是正确的。

要解决这个问题,您需要更改USING查询以生成具有唯一键的结果集。这是您的数据模型,您了解它的业务规则,因此您可以正确重写它。但可能是这样的:

  select 
    name,
    max(institution_cd) as institution_cd,
    institution_status,
    max(country_cd) as country_cd
  from (
    institution uni
  where
    uni.institution_status = 'ACTIVE' and
    uni.country_cd is not null
  group by
    name,
    institution_status
  order by
    name  
) uni

然后可以将MERGE ON子句简化为:

on
(
  to_t.INSTITUTION_CD = from_t.NAME
)

在子查询中使用MAX()是一个不雅观的难题。我希望你能应用更好的商业规则。

姜德容
2023-03-14

我认为你的主要问题是小组讨论。

请考虑以下示例:

 desc temp_inventory;
 Name                  Type
 --------------------- -----------
 WAREHOUSE_NO          NUMBER(2)
 ITEM_NO               NUMBER(10)
 ITEM_QUANTITY         NUMBER(10)

WAREHOUSE_NO    ITEM_NO    ITEM_QUANTITY
1               1000       100
1               2000       200
1               2000       300

如果我写了一个查询,希望warehouse\u no是唯一的:

select warehouse_no,item_quantity 
from temp_inventory 
group by warehouse_no,item_quantity

它将返回相同的3行。。相反,我想按..分组。。

select warehouse_no,sum(item_quantity)
from temp_inventory 
group by warehouse_no

这将使warehouse_no在这种情况下独一无二!

此外,在您有VARCHAR2列的情况下,您可以在它们上使用MAX、MIN作为聚合函数以及group by在查询中创建唯一键。

示例:

Select object_type, min(object_name) 
from user_objects group by object_type;

这将使object_type独一无二

所以请注意,如果有重复的,最终会根据聚合函数消除一些记录。

 类似资料:
  • 以下是SQL部分,我在调试代码时出错: ORA-00001:唯一约束主键违反T_LIAV_AGENT_STATE_APPROVAL... 这是主键约束依赖的2列AV_NAME_ID,AV_STATE... 我没有重复的数据...你认为还有其他原因吗?

  • 我正试图插入数据库,但我在日志上看到了这样的消息: 我找到了这个查询以获取违反的密钥:

  • 问题内容: 我正在使用Oracle数据库。我们的服务呼叫频繁失败。当我查看日志时,在表上看到以下异常 java.sql.BatchUpdateException:ORA-00001:违反了唯一约束(DBSCHEMA.IDX_CO_DETAILS)。 我已经检查了表上索引的索引名称DBSCHEMA.IDX_CO_DETAILS。 它不包含任何列的(INCLUDE_COLUMN为null)。我怎么知道

  • 我有一个迁移脚本之间的2个不同的模式数据库。脚本做了3件事:1。禁用约束2。将记录从旧架构插入到新架构3。启用约束 我发现这两个约束在旧的模式中是不存在的。这2个表的表结构定义有什么问题吗?

  • 我想知道对于这些类型的多线程场景是否有更可靠的锁处理。或者我需要添加一些东西来修复我的约束违规。 非常感谢。