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;
}







2















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 -



TABLE FOO



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 -



Output



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:









share|improve this question

























  • 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


















2















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 -



TABLE FOO



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 -



Output



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:









share|improve this question

























  • 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














2












2








2








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 -



TABLE FOO



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 -



Output



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:









share|improve this question
















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 -



TABLE FOO



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 -



Output



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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 wherever N_RA_ID self joins. I have added the MERGE 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











  • @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

















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












3 Answers
3






active

oldest

votes


















2














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





share|improve this answer


























  • Not really a workaround though, is it? :-)

    – mathguy
    Nov 16 '18 at 22:38



















2














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%'





share|improve this answer


























  • 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





    @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



















0














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%'





share|improve this answer
























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    2














    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





    share|improve this answer


























    • Not really a workaround though, is it? :-)

      – mathguy
      Nov 16 '18 at 22:38
















    2














    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





    share|improve this answer


























    • Not really a workaround though, is it? :-)

      – mathguy
      Nov 16 '18 at 22:38














    2












    2








    2







    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





    share|improve this answer















    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






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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



















    • 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













    2














    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%'





    share|improve this answer


























    • 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





      @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
















    2














    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%'





    share|improve this answer


























    • 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





      @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














    2












    2








    2







    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%'





    share|improve this answer















    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%'






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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





      @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



















    • 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





      @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

















    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











    0














    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%'





    share|improve this answer




























      0














      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%'





      share|improve this answer


























        0












        0








        0







        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%'





        share|improve this answer













        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%'






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 2 at 16:05









        Lukas EderLukas Eder

        138k74448987




        138k74448987






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine