Reputation: 6819
I have a MERGE statement that's giving me the dreaded ORA-00904: invalid identifier
error message. Note that the typical issues with the "invalid identifier" error are not present here - I'm not trying to update the joined column, nor have I misspelled my column names. I am attempting to use the oracle pseudo-column ORA_ROWSCN
in the USING
clause's SELECT
statement.
With these sample tables, I try to run
MERGE INTO MY_MERGE_TABLE D
USING
(SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt,
ORA_ROWSCN AS rowscn
FROM MY_SOURCE_TABLE) S
ON (D.PRIMARY_KEY = S.PRIMARY_KEY)
WHEN MATCHED THEN
UPDATE SET D.update_dt = GREATEST(D.update_dt, S.update_dt),
D.rowscn = GREATEST(D.rowscn, S.rowscn)
WHEN NOT MATCHED THEN
INSERT (D.PRIMARY_KEY, D.UPDATE_DT, D.ROWSCN)
VALUES (S.PRIMARY_KEY, S.UPDATE_DT, S.ROWSCN);
If I remove the pseudocolumn ora_rowscn from the USING clause, I no longer receive the error message, and the merge completes successfully.
MERGE INTO MY_MERGE_TABLE D
USING
(SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt
FROM MY_SOURCE_TABLE) S
ON (D.PRIMARY_KEY = S.PRIMARY_KEY)
WHEN MATCHED THEN
UPDATE SET D.update_dt = GREATEST(D.update_dt, S.update_dt)
WHEN NOT MATCHED THEN
INSERT (D.PRIMARY_KEY, D.UPDATE_DT)
VALUES (S.PRIMARY_KEY, S.UPDATE_DT);
If I instead place the query into a VIEW, I can then use the ora_rowscn successfully:
CREATE VIEW MY_VIEW AS
SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt,
ORA_ROWSCN AS rowscn
FROM MY_SOURCE_TABLE;
MERGE INTO MY_MERGE_TABLE D
USING (SELECT PRIMARY_KEY, UPDATE_DT, ROWSCN FROM MY_VIEW) S
ON (D.PRIMARY_KEY = S.PRIMARY_KEY)
WHEN MATCHED THEN
UPDATE SET D.update_dt = GREATEST(D.update_dt, S.update_dt),
D.rowscn = GREATEST(D.rowscn, S.rowscn)
WHEN NOT MATCHED THEN
INSERT (D.PRIMARY_KEY, D.UPDATE_DT, D.ROWSCN)
VALUES (S.PRIMARY_KEY, S.UPDATE_DT, S.ROWSCN);
Is there any way to do this without creating a VIEW for the query? I have to do this on many tables as part of an ETL process, and would prefer not to have to build several views.
EDIT: Based on Glenn's suggestion in the comments, I tried putting the query into a subquery:
MERGE INTO MY_MERGE_TABLE D
USING
(WITH QRY AS
(SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt,
ORA_ROWSCN AS rowscn
FROM MY_SOURCE_TABLE)
SELECT ORDER_ID, UPDATE_DT, ROWSCN FROM QRY)
ON (D.PRIMARY_KEY = S.PRIMARY_KEY)
WHEN MATCHED THEN
UPDATE SET D.update_dt = GREATEST(D.update_dt, S.update_dt),
D.rowscn = GREATEST(D.rowscn, S.rowscn)
WHEN NOT MATCHED THEN
INSERT (D.PRIMARY_KEY, D.UPDATE_DT, D.ROWSCN)
VALUES (S.PRIMARY_KEY, S.UPDATE_DT, S.ROWSCN);
This query still gives me the ORA-00904: invalid identifier
error message.
Here's DDL to recreate the issue.
CREATE TABLE MY_SOURCE_TABLE (
PRIMARY_KEY NUMBER,
CREATED_DT TIMESTAMP(6),
UPDATED_DT TIMESTAMP(6)
);
CREATE TABLE MY_MERGE_TABLE (
PRIMARY_KEY NUMBER,
UPDATED_DT TIMESTAMP(6),
ROWSCN NUMBER
);
INSERT INTO MY_SOURCE_TABLE (PRIMARY_KEY, CREATED_DT, UPDATED_DT)
VALUES (1, SYSDATE-2, SYSDATE);
INSERT INTO MY_SOURCE_TABLE (PRIMARY_KEY, CREATED_DT, UPDATED_DT)
VALUES (2, SYSDATE-1, NULL);
INSERT INTO MY_SOURCE_TABLE (PRIMARY_KEY, CREATED_DT, UPDATED_DT)
VALUES (3, SYSDATE-1, SYSDATE+1);
INSERT INTO MY_MERGE_TABLE (PRIMARY_KEY, UPDATED_DT, ROWSCN)
VALUES (1, SYSDATE-2, 0);
INSERT INTO MY_MERGE_TABLE (PRIMARY_KEY, UPDATED_DT, ROWSCN)
VALUES (2, SYSDATE-1, 0);
Upvotes: 3
Views: 1470
Reputation: 506
I ran your SQL and got the same error (on 11.2.0.1). Then I tried to run the select
SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt,
ORA_ROWSCN AS rowscn
FROM MY_SOURCE_TABLE;
Still got the ORA-00904: "UPDATE_DT": invalid identifier
error. Then I noticed that in your DDL, the column on MY_SOURCE_TABLE
is called UPDATED_DT
(i.e. with an extra D
character). Changing the references to that in your MERGE
statement made it work for me, hope that helps.
Upvotes: 5