ORA-38104 - What is workaround to updating column in ON clause in a MERGE?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have table FOO
with some ID values in col N_RA_ID
for MANUAL%
values in col V_CUST_NUMBER
and some matching values in col N_RA_ID
for NON-MANUAL values in col V_CUST_NUMBER
. Here is sample data -
I want to self join on col N_RA_ID
and wherever there is exact match, I want to update N_RA_ID
to null WHERE V_CUST_NUMBER LIKE 'MANUAL%'
so the output should look like -
I tried using a merge but got ORA-38104. Can anybody please help?
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.N_RA_ID = Z.N_RA_ID)
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
SQL Error: ORA-38104: Columns referenced in the ON Clause cannot be updated: "X"."N_RA_ID"
38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s"
*Cause: LHS of UPDATE SET contains the columns referenced in the ON Clause
*Action:
sql oracle sql-update oracle12c
add a comment |
I have table FOO
with some ID values in col N_RA_ID
for MANUAL%
values in col V_CUST_NUMBER
and some matching values in col N_RA_ID
for NON-MANUAL values in col V_CUST_NUMBER
. Here is sample data -
I want to self join on col N_RA_ID
and wherever there is exact match, I want to update N_RA_ID
to null WHERE V_CUST_NUMBER LIKE 'MANUAL%'
so the output should look like -
I tried using a merge but got ORA-38104. Can anybody please help?
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.N_RA_ID = Z.N_RA_ID)
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
SQL Error: ORA-38104: Columns referenced in the ON Clause cannot be updated: "X"."N_RA_ID"
38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s"
*Cause: LHS of UPDATE SET contains the columns referenced in the ON Clause
*Action:
sql oracle sql-update oracle12c
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
@ikram - By exact match, I meant whereverN_RA_ID
self joins. I have added theMERGE
statement I had ran.
– Reeya Oberoi
Nov 16 '18 at 22:14
add a comment |
I have table FOO
with some ID values in col N_RA_ID
for MANUAL%
values in col V_CUST_NUMBER
and some matching values in col N_RA_ID
for NON-MANUAL values in col V_CUST_NUMBER
. Here is sample data -
I want to self join on col N_RA_ID
and wherever there is exact match, I want to update N_RA_ID
to null WHERE V_CUST_NUMBER LIKE 'MANUAL%'
so the output should look like -
I tried using a merge but got ORA-38104. Can anybody please help?
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.N_RA_ID = Z.N_RA_ID)
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
SQL Error: ORA-38104: Columns referenced in the ON Clause cannot be updated: "X"."N_RA_ID"
38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s"
*Cause: LHS of UPDATE SET contains the columns referenced in the ON Clause
*Action:
sql oracle sql-update oracle12c
I have table FOO
with some ID values in col N_RA_ID
for MANUAL%
values in col V_CUST_NUMBER
and some matching values in col N_RA_ID
for NON-MANUAL values in col V_CUST_NUMBER
. Here is sample data -
I want to self join on col N_RA_ID
and wherever there is exact match, I want to update N_RA_ID
to null WHERE V_CUST_NUMBER LIKE 'MANUAL%'
so the output should look like -
I tried using a merge but got ORA-38104. Can anybody please help?
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.N_RA_ID = Z.N_RA_ID)
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
SQL Error: ORA-38104: Columns referenced in the ON Clause cannot be updated: "X"."N_RA_ID"
38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s"
*Cause: LHS of UPDATE SET contains the columns referenced in the ON Clause
*Action:
sql oracle sql-update oracle12c
sql oracle sql-update oracle12c
edited Nov 17 '18 at 10:38
William Robertson
8,55232233
8,55232233
asked Nov 16 '18 at 21:52
Reeya OberoiReeya Oberoi
36111027
36111027
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
@ikram - By exact match, I meant whereverN_RA_ID
self joins. I have added theMERGE
statement I had ran.
– Reeya Oberoi
Nov 16 '18 at 22:14
add a comment |
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
@ikram - By exact match, I meant whereverN_RA_ID
self joins. I have added theMERGE
statement I had ran.
– Reeya Oberoi
Nov 16 '18 at 22:14
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
@ikram - By exact match, I meant wherever
N_RA_ID
self joins. I have added the MERGE
statement I had ran.– Reeya Oberoi
Nov 16 '18 at 22:14
@ikram - By exact match, I meant wherever
N_RA_ID
self joins. I have added the MERGE
statement I had ran.– Reeya Oberoi
Nov 16 '18 at 22:14
add a comment |
3 Answers
3
active
oldest
votes
You can do a simple update with an exists ()
check:
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
The main update filters first on all rows starting with 'MANUAL', and the subquery inside the exists()
looks for any row in the table with the same ID, but which does not start with 'MANUAL'. If there is no such non-manual row then that clause is false and the manual row is left untouched; if there is a match then the row is updated.
Demo:
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036 589478
BHASAD 589478
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
1 row updated.
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036
BHASAD 589478
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
add a comment |
The usual workaround is to select T2.ROWID as RID
in the USING
clause, and then instead of matching on N_RA_ID
you match ON X.ROWID = Z.RID
.
Like so:
MERGE INTO FOO X
USING (
SELECT T2.ROWID AS RID, -- ADD THIS HERE
T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.ROWID = Z.RID) -- CHANGE THE "ON" CLAUSE LIKE THIS
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
Your answer seems to be workaround. I have a question, when you apply this conditionON (X.ROWID = Z.RID)
, does it return bothMANUAL
andNON MANUAL
rows up to that point? And then we go ahead and update the row which isMANUAL%
? Is that right?
– Reeya Oberoi
Nov 16 '18 at 22:51
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING inZ
(the view in theUSING
clause) other thanT2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why theUPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications ofMERGE
.
– mathguy
Nov 16 '18 at 23:01
add a comment |
As of Oracle 18c, there exist some workarounds that can be applied to such MERGE
statements, which outsmart the parser who checks for ORA-38104 preconditions. For example, you could use row value expressions with an additional dummy column comparison:
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON ((X.N_RA_ID, 'dummy') = ((Z.N_RA_ID, 'dummy')))
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53345919%2fora-38104-what-is-workaround-to-updating-column-in-on-clause-in-a-merge%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can do a simple update with an exists ()
check:
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
The main update filters first on all rows starting with 'MANUAL', and the subquery inside the exists()
looks for any row in the table with the same ID, but which does not start with 'MANUAL'. If there is no such non-manual row then that clause is false and the manual row is left untouched; if there is a match then the row is updated.
Demo:
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036 589478
BHASAD 589478
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
1 row updated.
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036
BHASAD 589478
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
add a comment |
You can do a simple update with an exists ()
check:
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
The main update filters first on all rows starting with 'MANUAL', and the subquery inside the exists()
looks for any row in the table with the same ID, but which does not start with 'MANUAL'. If there is no such non-manual row then that clause is false and the manual row is left untouched; if there is a match then the row is updated.
Demo:
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036 589478
BHASAD 589478
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
1 row updated.
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036
BHASAD 589478
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
add a comment |
You can do a simple update with an exists ()
check:
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
The main update filters first on all rows starting with 'MANUAL', and the subquery inside the exists()
looks for any row in the table with the same ID, but which does not start with 'MANUAL'. If there is no such non-manual row then that clause is false and the manual row is left untouched; if there is a match then the row is updated.
Demo:
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036 589478
BHASAD 589478
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
1 row updated.
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036
BHASAD 589478
You can do a simple update with an exists ()
check:
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
The main update filters first on all rows starting with 'MANUAL', and the subquery inside the exists()
looks for any row in the table with the same ID, but which does not start with 'MANUAL'. If there is no such non-manual row then that clause is false and the manual row is left untouched; if there is a match then the row is updated.
Demo:
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036 589478
BHASAD 589478
update foo f1
set n_ra_id = null
where v_cust_number like 'MANUAL%'
and exists (
select *
from foo f2
where f2.n_ra_id = f1.n_ra_id
and v_cust_number not like 'MANUAL%'
);
1 row updated.
select * from foo;
V_CUST_NU N_RA_ID
--------- ----------
MANUAL033 17024
MANUAL034 589469
MANUAL035 589470
MANUAL036
BHASAD 589478
edited Nov 16 '18 at 22:41
Reeya Oberoi
36111027
36111027
answered Nov 16 '18 at 22:25
Alex PooleAlex Poole
135k6110185
135k6110185
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
add a comment |
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
Not really a workaround though, is it? :-)
– mathguy
Nov 16 '18 at 22:38
add a comment |
The usual workaround is to select T2.ROWID as RID
in the USING
clause, and then instead of matching on N_RA_ID
you match ON X.ROWID = Z.RID
.
Like so:
MERGE INTO FOO X
USING (
SELECT T2.ROWID AS RID, -- ADD THIS HERE
T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.ROWID = Z.RID) -- CHANGE THE "ON" CLAUSE LIKE THIS
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
Your answer seems to be workaround. I have a question, when you apply this conditionON (X.ROWID = Z.RID)
, does it return bothMANUAL
andNON MANUAL
rows up to that point? And then we go ahead and update the row which isMANUAL%
? Is that right?
– Reeya Oberoi
Nov 16 '18 at 22:51
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING inZ
(the view in theUSING
clause) other thanT2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why theUPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications ofMERGE
.
– mathguy
Nov 16 '18 at 23:01
add a comment |
The usual workaround is to select T2.ROWID as RID
in the USING
clause, and then instead of matching on N_RA_ID
you match ON X.ROWID = Z.RID
.
Like so:
MERGE INTO FOO X
USING (
SELECT T2.ROWID AS RID, -- ADD THIS HERE
T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.ROWID = Z.RID) -- CHANGE THE "ON" CLAUSE LIKE THIS
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
Your answer seems to be workaround. I have a question, when you apply this conditionON (X.ROWID = Z.RID)
, does it return bothMANUAL
andNON MANUAL
rows up to that point? And then we go ahead and update the row which isMANUAL%
? Is that right?
– Reeya Oberoi
Nov 16 '18 at 22:51
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING inZ
(the view in theUSING
clause) other thanT2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why theUPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications ofMERGE
.
– mathguy
Nov 16 '18 at 23:01
add a comment |
The usual workaround is to select T2.ROWID as RID
in the USING
clause, and then instead of matching on N_RA_ID
you match ON X.ROWID = Z.RID
.
Like so:
MERGE INTO FOO X
USING (
SELECT T2.ROWID AS RID, -- ADD THIS HERE
T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.ROWID = Z.RID) -- CHANGE THE "ON" CLAUSE LIKE THIS
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
The usual workaround is to select T2.ROWID as RID
in the USING
clause, and then instead of matching on N_RA_ID
you match ON X.ROWID = Z.RID
.
Like so:
MERGE INTO FOO X
USING (
SELECT T2.ROWID AS RID, -- ADD THIS HERE
T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON (X.ROWID = Z.RID) -- CHANGE THE "ON" CLAUSE LIKE THIS
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
edited Nov 16 '18 at 22:37
answered Nov 16 '18 at 22:30
mathguymathguy
26.7k51737
26.7k51737
Your answer seems to be workaround. I have a question, when you apply this conditionON (X.ROWID = Z.RID)
, does it return bothMANUAL
andNON MANUAL
rows up to that point? And then we go ahead and update the row which isMANUAL%
? Is that right?
– Reeya Oberoi
Nov 16 '18 at 22:51
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING inZ
(the view in theUSING
clause) other thanT2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why theUPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications ofMERGE
.
– mathguy
Nov 16 '18 at 23:01
add a comment |
Your answer seems to be workaround. I have a question, when you apply this conditionON (X.ROWID = Z.RID)
, does it return bothMANUAL
andNON MANUAL
rows up to that point? And then we go ahead and update the row which isMANUAL%
? Is that right?
– Reeya Oberoi
Nov 16 '18 at 22:51
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING inZ
(the view in theUSING
clause) other thanT2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why theUPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications ofMERGE
.
– mathguy
Nov 16 '18 at 23:01
Your answer seems to be workaround. I have a question, when you apply this condition
ON (X.ROWID = Z.RID)
, does it return both MANUAL
and NON MANUAL
rows up to that point? And then we go ahead and update the row which is MANUAL%
? Is that right?– Reeya Oberoi
Nov 16 '18 at 22:51
Your answer seems to be workaround. I have a question, when you apply this condition
ON (X.ROWID = Z.RID)
, does it return both MANUAL
and NON MANUAL
rows up to that point? And then we go ahead and update the row which is MANUAL%
? Is that right?– Reeya Oberoi
Nov 16 '18 at 22:51
1
1
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING in
Z
(the view in the USING
clause) other than T2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why the UPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications of MERGE
.– mathguy
Nov 16 '18 at 23:01
@ReeyaOberoi - Correct. In addition, you don't really need to select ANYTHING in
Z
(the view in the USING
clause) other than T2.ROWID as RID
, since you are not really using any other bit of data from the table - all you need is the simple fact that a match is found. (Which is why the UPDATE
with a semi-join condition works, as shown by Alex Poole.) The workaround shown here is more general though, it works in other applications of MERGE
.– mathguy
Nov 16 '18 at 23:01
add a comment |
As of Oracle 18c, there exist some workarounds that can be applied to such MERGE
statements, which outsmart the parser who checks for ORA-38104 preconditions. For example, you could use row value expressions with an additional dummy column comparison:
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON ((X.N_RA_ID, 'dummy') = ((Z.N_RA_ID, 'dummy')))
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
add a comment |
As of Oracle 18c, there exist some workarounds that can be applied to such MERGE
statements, which outsmart the parser who checks for ORA-38104 preconditions. For example, you could use row value expressions with an additional dummy column comparison:
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON ((X.N_RA_ID, 'dummy') = ((Z.N_RA_ID, 'dummy')))
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
add a comment |
As of Oracle 18c, there exist some workarounds that can be applied to such MERGE
statements, which outsmart the parser who checks for ORA-38104 preconditions. For example, you could use row value expressions with an additional dummy column comparison:
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON ((X.N_RA_ID, 'dummy') = ((Z.N_RA_ID, 'dummy')))
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
As of Oracle 18c, there exist some workarounds that can be applied to such MERGE
statements, which outsmart the parser who checks for ORA-38104 preconditions. For example, you could use row value expressions with an additional dummy column comparison:
MERGE INTO FOO X
USING (
SELECT T1.V_CUST_NUMBER AS MAN_CUST,T1.N_RA_ID, T2.V_CUST_NUMBER
FROM FOO T1
JOIN FOO T2
ON T1.N_RA_ID = T2.N_RA_ID
AND UPPER(T1.V_CUST_NUMBER) NOT LIKE 'MANUAL%'
) Z
ON ((X.N_RA_ID, 'dummy') = ((Z.N_RA_ID, 'dummy')))
WHEN MATCHED THEN UPDATE
SET X.N_RA_ID = null
WHERE UPPER(X.V_CUST_NUMBER) LIKE 'MANUAL%'
answered Jan 2 at 16:05
Lukas EderLukas Eder
138k74448987
138k74448987
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53345919%2fora-38104-what-is-workaround-to-updating-column-in-on-clause-in-a-merge%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What do you mean by exact match? Can you share query that you tried using merge
– ikram
Nov 16 '18 at 22:08
@ikram - By exact match, I meant wherever
N_RA_ID
self joins. I have added theMERGE
statement I had ran.– Reeya Oberoi
Nov 16 '18 at 22:14