Sql 基于Select查询的Oracle Update语句w/连接不起作用

Sql 基于Select查询的Oracle Update语句w/连接不起作用,sql,oracle,join,sql-update,Sql,Oracle,Join,Sql Update,我正在尝试基于包含联接的select查询应用更新查询,但它不起作用 UPDATE ( SELECT LOCATION_NUM, LOCATION_TYPE, LOCATION_CITY, ACCOUNT_NUM FROM TBLSALES T1 INNER JOIN TBLCENTER T2 ON T2.LOCATION_ID = T1.LOCATION_ID INNER JOIN TBLACCOUNT T3 ON T3.ACCOUNT_ID =

我正在尝试基于包含联接的select查询应用更新查询,但它不起作用

UPDATE (
  SELECT 
    LOCATION_NUM, LOCATION_TYPE, LOCATION_CITY, ACCOUNT_NUM
  FROM 
    TBLSALES T1
    INNER JOIN TBLCENTER  T2 ON T2.LOCATION_ID = T1.LOCATION_ID
    INNER JOIN TBLACCOUNT T3 ON T3.ACCOUNT_ID  = T1.ACCOUNT_ID
  WHERE
    LOCATION_CITY = 'New York' 
    AND LOCATION_NUM LIKE 'NY1%' 
    AND ACCOUNT_NUM IN ('40001','40002','40003')
)
SET 
   LOCATION_TYPE = 'TYPE 1'
;
运行它时,我会出现以下错误:

SQL Error: ORA-01779: cannot modify a column which maps to a non key preserved table

当您尝试通过join进行更新时(就像您一样),必须满足两个条件:

  • 查找表中的查找键(您有两个表,因此两个查找键,
    tblcenter
    中的
    location\u id
    tblaccount
    中的
    account\u id
    )不得重复;它必须是“唯一的”(在“无重复值”的意义上)。这是一个明显的逻辑要求;如果不满足,那么基于模糊查找的更新问题就是胡说八道
  • Oracle需要在解析时预先知道唯一性将保持不变。也就是说,表在这些列上必须具有唯一的约束和/或唯一的索引。这不是逻辑要求,而是Oracle实施要求。错误消息告诉您,两个查找表中至少有一个(可能两个都有)不满足第二个条件
如何解决这个问题?您有几个选择:

  • 最简单:在这些表中的列上创建唯一约束(或主键约束)。很可能它们本来就是PK的,但事实并非如此。这里请注意-“应用程序中维护的主键”或“唯一”约束-我被告知PeopleSoft会这样做,例如-没有帮助

  • 您可以通过MERGE语句进行更新。语法将非常相似。不同之处在于,MERGE等待直到它看到所有数据,并且仅当它事实上在实际数据中发现不应该发现重复项时才会抱怨

  • 效率稍低,但有一个明显的解决办法:将语句重写为

    更新TBL销售 设置位置\类型='类型1' 其中(……)

…直到现在我才意识到我并没有真正加入WHERE子句。如果您可以说(在UPDATE语句本身中!)哪些列来自哪些表,这会有所帮助。我猜位置_NUM来自销售表?那么WHERE子句应该是

where location_num like 'NY1%'
  and location_num in (select location_num from the three-way join)

(假设这是您最初的UPDATE语句的意思)。

当您尝试通过join进行更新时,就像您一样,必须满足两个条件:

  • 查找表中的查找键(您有两个表,因此两个查找键,
    tblcenter
    中的
    location\u id
    tblaccount
    中的
    account\u id
    )不得重复;它必须是“唯一的”(在“无重复值”的意义上)。这是一个明显的逻辑要求;如果不满足,那么基于模糊查找的更新问题就是胡说八道
  • Oracle需要在解析时预先知道唯一性将保持不变。也就是说,表在这些列上必须具有唯一的约束和/或唯一的索引。这不是逻辑要求,而是Oracle实施要求。错误消息告诉您,两个查找表中至少有一个(可能两个都有)不满足第二个条件
如何解决这个问题?您有几个选择:

  • 最简单:在这些表中的列上创建唯一约束(或主键约束)。很可能它们本来就是PK的,但事实并非如此。这里请注意-“应用程序中维护的主键”或“唯一”约束-我被告知PeopleSoft会这样做,例如-没有帮助

  • 您可以通过MERGE语句进行更新。语法将非常相似。不同之处在于,MERGE等待直到它看到所有数据,并且仅当它事实上在实际数据中发现不应该发现重复项时才会抱怨

  • 效率稍低,但有一个明显的解决办法:将语句重写为

    更新TBL销售 设置位置\类型='类型1' 其中(……)

…直到现在我才意识到我并没有真正加入WHERE子句。如果您可以说(在UPDATE语句本身中!)哪些列来自哪些表,这会有所帮助。我猜位置_NUM来自销售表?那么WHERE子句应该是

where location_num like 'NY1%'
  and location_num in (select location_num from the three-way join)
(假设这是您原始更新语句的含义)