我正在尝试根据已加入的选择查询应用更新查询,但它无效。
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
答案 0 :(得分:2)
当你尝试通过加入更新时,就像你一样,必须有两个条件:
location_id
中的两个查找键tblcenter
和account_id
中的tblaccount
)不得有重复项;它必须是"独特的" (在"意义上没有重复的值")。这是一个明显的逻辑要求;如果不满足,基于模糊查找的更新问题是无稽之谈。如何解决这个问题?您有几个选择:
最简单:在这些表中的那些列上创建UNIQUE约束(或PRIMARY KEY约束)。很可能他们意味着首先是PK,但他们并非如此。请注意 - "主键"或"独特的"约束在应用程序中维护 - 正如我被告知PeopleSoft所做的那样 - 例如 - 没有帮助。
您可以通过MERGE语句进行更新。语法非常相似。不同之处在于MERGE会等到它看到所有数据,并且只有在实际上在实际数据中找到重复项时才会抱怨,其中不应该找到重复数据。
效率稍差,但有一个明显的解决方法:将语句重写为
更新tblsales 设置location_type =' TYPE 1' 其中(.....)
......直到现在我才意识到我并没有真正进入WHERE子句。如果您说(在UPDATE语句本身!)哪些列来自哪些表,这将有所帮助。我猜想LOCATION_NUM来自SALES表?那么WHERE子句应该类似于
where location_num like 'NY1%'
and location_num in (select location_num from the three-way join)
(假设这是您原始UPDATE语句的含义)。