我有一个存储过程,我想在其中更新一些列,所以我写了下面的代码:
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:不能更新ON子句中引用的列:“ I”。“ SAP_ID”
我在做什么错了?
答案 0 :(得分:4)
您正在将源表连接到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;
答案 1 :(得分:3)
错误消息告诉您问题是什么-MERGE语句无法更新ON子句中使用的列-甚至告诉您问题出在哪一列:"I"."SAP_ID"
。
由于在您的WHEN MATCHED分支中有此行,因此Oracle催促ORA-38104
I.SAP_ID = O.SAP_ID;
将其删除,您的问题就消失了。幸运的是,该行是不必要的:I.SAP_ID
已经等于O.SAP_ID
,否则该记录就不会在MATCHED分支下进行。
原因很简单:事务一致性。 MERGE语句对由USING子句和ON子句定义的一组记录进行操作。更新ON子句中使用的列会威胁到该集合的完整性,因此Oracle禁止这样做。