Oracle Fusion Déclaration Comportement lorsque ora_rowscn est en clause USING
-
27-10-2019 - |
Question
J'ai une déclaration MERGE qui me donne le message d'erreur de ORA-00904: invalid identifier
redoutée. Notez que les problèmes typiques avec l'erreur « identifiant invalide » ne sont pas présents ici - je ne cherche pas à mettre à jour la colonne jointe, et je n'ai orthographié mes noms de colonnes. I h d'essayer d'utiliser la pseudo-ORA_ROWSCN
colonne oracle dans la déclaration de USING
de la clause SELECT
.
Avec ces exemples de tableaux, je tente d'exécuter
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);
Si je supprime la ora_rowscn de la pseudo-colonne clause USING, je ne reçois plus le message d'erreur, et la fusion se termine normalement.
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);
Si je place au lieu de la requête en vue, je peux alors utiliser le ora_rowscn avec succès:
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);
Est-il possible de le faire sans créer une vue pour la requête? Je dois le faire sur de nombreuses tables dans le cadre d'un processus ETL, et préférerais ne pas avoir à construire plusieurs vues.
EDIT: Sur la base de la suggestion de Glenn dans les commentaires, j'ai essayé de mettre la requête dans une sous-requête:
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);
Cette requête me donne toujours le message d'erreur ORA-00904: invalid identifier
.
est ici pour DDL recréent la question.
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);
La solution
J'ai couru SQL et obtenu la même erreur (sur 11.2.0.1). Alors j'ai essayé de lancer le select
SELECT PRIMARY_KEY,
COALESCE (UPDATE_DT, CREATED_DT) update_dt,
ORA_ROWSCN AS rowscn
FROM MY_SOURCE_TABLE;
Vous avez encore l'erreur de ORA-00904: "UPDATE_DT": invalid identifier
. Ensuite, je remarque que dans votre LDD, la colonne MY_SOURCE_TABLE
est appelée UPDATED_DT
(à savoir avec un caractère D
supplémentaire). Modification des références à cela dans votre déclaration de MERGE
fait fonctionner pour moi, l'espoir qui aide.