尝试使用合并更新我的 table 时出现 ORA-38104

ORA-38104 when trying to update my table using merge

我有一个存储过程,我想在其中更新一些列,所以我写了下面的代码:

PROCEDURE UPDATE_MST_INFO_BKC (
    P_SAPID IN   NVARCHAR2
) AS
BEGIN
    MERGE INTO tbl_ipcolo_billing_mst I 
    USING (
            SELECT
                R4G_STATE,                        -- poilitical state name
                R4G_STATECODE,                    -- poilitical state code
                CIRCLE,                           -- city name                                                            
                NE_ID,
                LATITUDE,
                LONGITUDE,
                SAP_ID

            FROM
                R4G_OSP.ENODEB
            WHERE
                SAP_ID = P_SAPID
                AND ROWNUM = 1
            )
    O ON ( I.SAP_ID = O.SAP_ID )
    WHEN MATCHED THEN 
    UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
               I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
                I.CITY_NAME = O.CIRCLE,
                I.NEID = O.NE_ID,
                I.FACILITY_LATITUDE = O.LATITUDE,
                I.FACILITY_LONGITUDE = O.LONGITUDE,
                I.SAP_ID = O.SAP_ID;               

END UPDATE_MST_INFO_BKC;

但它给了我错误

ORA-38104: Columns referenced in the ON Clause cannot be updated: "I"."SAP_ID"

我做错了什么?

错误消息会告诉您问题所在 - MERGE 语句无法更新 ON 子句中使用的列 - 甚至会告诉您问题所在的列:"I"."SAP_ID".

所以 Oracle 抛出 ORA-38104 因为你的 WHEN MATCHED 分支中的这一行

I.SAP_ID = O.SAP_ID; 

删除它,您的问题就会消失。幸运的是,该行是不必要的:I.SAP_ID 已经等于 O.SAP_ID,否则记录将不会进入 MATCHED 分支。

原因很简单:事务一致性。 MERGE 语句对一组由 USING 子句和 ON 子句定义的记录进行操作。更新 ON 子句中使用的列会威胁到该集合的完整性,因此 Oracle 禁止这样做。

您正在 I.SAP_ID = O.SAP_ID 上将源表连接到目标表,然后在匹配时尝试更新它们并设置 I.SAP_ID = O.SAP_ID。您无法更新连接中使用的列...为什么要更新,因为您已经确定这些值是相等的。

只需删除 UPDATE:

的最后一行
...
O ON ( I.SAP_ID = O.SAP_ID )
WHEN MATCHED THEN 
UPDATE SET I.POLITICAL_STATE_NAME = O.R4G_STATE,
           I.POLITICAL_STATE_CODE = O.R4G_STATECODE,
           I.CITY_NAME = O.CIRCLE,
           I.NEID = O.NE_ID,
           I.FACILITY_LATITUDE = O.LATITUDE,
           I.FACILITY_LONGITUDE = O.LONGITUDE;