Note that there are some explanatory texts on larger screens.

plurals
  1. POUpdating a Join View without getting Non Key-Preserved Error
    primarykey
    data
    text
    <p>I have a view created in an Oracle 11g database that is comprised of two joined tables like so:</p> <pre><code>CREATE FORCE VIEW my_dataview ( key1, key2, column_from_table1, column_from_table2 ) AS SELECT key1, key2, column_from_table1, column_from_table2 FROM table1 NATURAL LEFT OUTER JOIN table2; </code></pre> <p>where both source tables have two primary keys named <code>key1</code> and <code>key2</code>. The data is being aggregated correctly, but I cannot update any of the columns from <code>table2</code> directly from the view.</p> <p>If I were to execute the following update,</p> <pre><code>UPDATE my_dataview SET column_from_table2 = 'Hello, world' WHERE key1 = 1234 AND key2 = 12; </code></pre> <p>the error it gives is <code>ORA-01779 cannot modify a column which maps to a non key-preserved table</code>. It also highlights <code>column_from_table2</code>. If I were to execute the same command, but set <code>column_from_table1</code> instead, it works. I think that may be because table1 is the required table in the join.</p> <p>I first thought that maybe since I'm joining on the primary keys, and there is only one resulting column in the view, that would explain my problem. But even adding in the separate <code>table2.key1</code> and <code>table2.key2</code> columns to the view did not change anything, except replicating data unnecessarily.</p> <p>I know it is possible to update a view using an INSTEAD OF trigger, but I would prefer to keep this as clean I can -- that seems more like a hack than a solution anyways.</p> <p>So to summarize my question, what is the best plan of action for enabling insert, update, and delete on a join view so as to not even be able to tell it is a view comprised of two separate tables at all?</p> <p>Table definitions as requested:</p> <pre><code>CREATE TABLE table1 ( key1 NUMBER(5) NOT NULL, key2 NUMBER(2) NOT NULL, column_from_table_1 DATE ); CREATE UNIQUE INDEX pk_table1_index ON table1 (key1, key2); ALTER TABLE table1 ADD ( CONSTRAINT table1_Pkey PRIMARY KEY (key1, key2) USING INDEX pk_table1_index ENABLE VALIDATE); CREATE TABLE table2 ( key1 NUMBER(5) NOT NULL, key2 NUMBER(2) NOT NULL, column_from_table_2 VARCHAR2(20) ); CREATE UNIQUE INDEX pk_table2_index ON table2 (key1, key2); ALTER TABLE table2 ADD ( CONSTRAINT table2_Pkey PRIMARY KEY (key1, key2) USING INDEX pk_table2_index ENABLE VALIDATE); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload