Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MERGE using a rowtype variable in PL/SQL on Oracle?

With a variable bar of the type foo%ROWTYPE I can do both INSERT and UPDATE in PL/SQL:

INSERT INTO foo VALUES bar;
UPDATE foo SET ROW = bar WHERE id = bar.id;

But how do I do a MERGE? The following approach generates the error message below:

MERGE INTO foo USING bar ON foo.id = bar.id
WHEN MATCHED THEN UPDATE SET ROW = bar
WHEN NOT MATCHED THEN INSERT VALUES bar;

PL/SQL: ORA-00942: table or view does not exist

like image 523
Anders Avatar asked Nov 16 '15 17:11

Anders


People also ask

How do I declare a Rowtype variable in PL SQL?

The %ROWTYPE attribute, used to declare PL/SQL variables of type record with fields that correspond to the columns of a table or view, is supported by the Db2® data server. Each field in a PL/SQL record assumes the data type of the corresponding column in the table. A record is a named, ordered collection of fields.

What is the use of Rowtype in PL SQL?

The %ROWTYPE attribute is used to define a record with fields corresponding to all of the columns that are fetched from a cursor or cursor variable. Each field assumes the data type of its corresponding column. The %ROWTYPE attribute is prefixed by a cursor name or a cursor variable name.

How do you declare a variable with %type attribute?

The data type of this column or variable is assigned to the variable being declared. If the data type of the column or variable changes, there is no need to modify the declaration code. The %TYPE attribute can also be used with formal parameter declarations.

What is a Rowtype variable?

The %ROWTYPE attribute provides a record type that represents a row in a database table. The record can store an entire row of data selected from the table or fetched from a cursor or cursor variable. Variables declared using %ROWTYPE are treated like those declared using a datatype name.


1 Answers

The answer MichaelS gives in the thread mentioned above should work fine. The error message you're receiving (ORA-38104: Columns referenced in the ON Clause cannot be updated: foo.id) suggests you're trying to do something similar to the following:

merge into foo
  using (select null from dual)
  on (foo.id = bar.id)
  when matched then update set foo.id = bar.id, foo.another_field = bar.another_field
  when not matched then insert VALUES bar;

As the error states, columns referenced in the "ON" clause cannot be updated. As such, the following would work fine:

merge into foo
  using (select null from dual)
  on (foo.id = bar.id)
  when matched then update set foo.another_field = bar.another_field
  when not matched then insert VALUES bar;

If you really need to update foo.id, there is a possible solution here: How to avoid ORA-3814 error on merge?

Edit

A possible alternative would be to do the following:

update foo set row = bar where foo.id = bar.id;

if sql%rowcount = 0 then
  insert into foo values bar;
end if;

This should essentially equate to doing the same thing as the merge statement.

like image 141
Chrisrs2292 Avatar answered Sep 17 '22 12:09

Chrisrs2292