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
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With