J'ai une vue créée dans une base de données Oracle 11g qui est composée de deux tables jointes comme suit :
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;
où les deux tables sources ont deux clés primaires nommées key1
y key2
. Les données sont agrégées correctement, mais je ne peux mettre à jour aucune des colonnes de table2
directement de la vue.
Si je devais exécuter la mise à jour suivante,
UPDATE my_dataview SET column_from_table2 = 'Hello, world'
WHERE key1 = 1234
AND key2 = 12;
l'erreur qu'il donne est la suivante ORA-01779 cannot modify a column which maps to a non key-preserved table
. Il met également l'accent sur column_from_table2
. Si j'exécute la même commande, mais en définissant column_from_table1
au lieu de cela, cela fonctionne. Je pense que cela est dû au fait que table1 est la table requise dans la jointure.
J'ai d'abord pensé que, puisque je fais une jointure sur les clés primaires et qu'il n'y a qu'une seule colonne résultante dans la vue, cela expliquerait mon problème. Mais même en ajoutant la colonne table2.key1
y table2.key2
à la vue n'a rien changé, si ce n'est de répliquer les données inutilement.
Je sais qu'il est possible de mettre à jour une vue en utilisant un trigger INSTEAD OF, mais je préférerais garder cela aussi propre que possible - cela ressemble plus à un hack qu'à une solution de toute façon.
Pour résumer ma question, quel est le meilleur plan d'action pour permettre l'insertion, la mise à jour et la suppression sur une vue de jointure de manière à ce qu'on ne puisse même pas dire qu'il s'agit d'une vue composée de deux tables distinctes ?
Définitions des tableaux comme demandé :
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);