Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to MERGE when the target table has invisible columns?

Stew AshtonJan 25 2015 — edited Feb 2 2015

Oracle Database 12.1.0.2.0 running on Oracle Linux 6.4:

While studying MERGE with invisible columns, I discovered that invisible columns in the target table cannot be read. The workaround appears to be

MERGE INTO (SELECT <column list> FROM <target table>) AS <alias>

However, the documentation does not seem to allow this. Here are the details.

Test data

> CREATE TABLE t_target(

  k1 NUMBER PRIMARY KEY,

  c1 NUMBER,

  i1 NUMBER invisible

)

table T_TARGET created.

> INSERT INTO t_target (k1,c1,i1)

SELECT 2, 2, 2 FROM dual

UNION ALL

SELECT 3, 3, 3 FROM dual

UNION ALL

SELECT 4, 4, 4 FROM dual

3 rows inserted.

> CREATE TABLE t_source(

  k1 NUMBER PRIMARY KEY,

  c1 NUMBER,

  i1 NUMBER invisible

)

table T_SOURCE created.

> INSERT INTO t_source (k1,c1,i1)

SELECT 1, 1, 1 FROM dual

UNION ALL

SELECT 2, 2, 9999 FROM dual

UNION ALL

SELECT 3, 3, 3 FROM dual

3 rows inserted.

First try

Please note that I have a WHERE clause within the WHEN MATCHED clause. Its purpose is to avoid updating a row when the data is already correct. The WHERE clause tries to read the invisible column from the target table.

> MERGE INTO t_target o

USING (

  SELECT k1, c1, i1 FROM t_source

) n

ON (o.k1 = n.k1)

WHEN MATCHED THEN UPDATE SET

  c1=n.c1, i1=n.i1

  WHERE 1 IN (

    decode(o.c1,n.c1,0,1),

    decode(o.i1,n.i1,0,1)

  )

WHEN NOT MATCHED THEN INSERT

  (k1, c1, i1)

  VALUES(n.k1, n.c1, n.i1)

...

Error at Command Line : 10 Column : 12

Error report -

SQL Error: ORA-00904: "O"."I1": invalid identifier

As you can see, I put a subquery after the USING clause so that "n.i1" would be "visible", but that's not enough since the "I1" column in the target table is still invisible.

Second try

> MERGE INTO (

  SELECT k1, c1, i1 FROM t_target

) o

USING (

  SELECT k1, c1, i1 FROM t_source

) n

ON (o.k1 = n.k1)

WHEN MATCHED THEN UPDATE SET

  c1=n.c1, i1=n.i1

  WHERE 1 IN (

    decode(o.c1,n.c1,0,1),

    decode(o.i1,n.i1,0,1)

  )

WHEN NOT MATCHED THEN INSERT

  (k1, c1, i1)

  VALUES(n.k1, n.c1, n.i1)

2 rows merged.

Here I used a subquery in the INTO clause as well, and it worked.

Unfortunately, this doesn't seem to be allowed in the documentation: INTO refers to a table or view as schema objects.

Description of merge.gif follows

My question is:

How can I refer to invisible columns in the target table without creating a new object? My workaround using a subquery seems to work fine, but can I recommend it if it is not documented?

Can I substitute an "inline view" for a view and still be supported?

This post has been answered by unknown-7404 on Jan 25 2015
Jump to Answer
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 2 2015
Added on Jan 25 2015
10 comments
832 views