J'écris actuellement des instructions de mise à jour afin de maintenir une table interrogeable constamment à jour. Le schéma est identique entre les deux tables et le contenu n'est pas important:
STAGING
ID
NAME
COUNT
PRODUCTION
ID
NAME
COUNT
Ma déclaration de mise à jour se présente comme suit:
update PRODUCTION
set name = (select stage.name from staging stage where stage.name=name and rownum <2),
count = (select stage.countfrom staging stage where stage.count=count and rownum <2);
Les deux choses à noter sont que 1) Il n'y a pas de clause where à la fin de ma mise à jour (cela peut être le problème) et 2) tous les enregistrements après avoir été mis à jour ont les mêmes valeurs. Ce que je veux dire par ceci est le suivant:
BEFORE UPDATE:
1,"JOHN", 12;
2,"STEVE",15;
3,"BETTY",2;
AFTER UPDATE
1,"JOHN", 12;
2,"JOHN",12;
3,"JOHN",12;
Ma question est la suivante: comment puis-je résoudre ce problème de sorte que le tableau reflète correctement les "nouvelles" données issues du stockage intermédiaire en tant que mise à jour SQL correcte?
METTRE &AGRAVE; JOUR
Ainsi, mes données de transfert pourraient coïncider par hasard ce qui est dans PRODUCTION
et aux fins de la discussion, elles:
STAGING DATA TO MERGE:
1,"JOHN", 12;
2,"STEVE",15;
3,"BETTY",2;
METTRE À JOUR le second
La requête que je voudrais lancer serait la suivante:
update PRODUCTION
set production.name = staging.name,
production.count = staging.count
where production.name = staging.name;
Cela entraîne toutefois des problèmes d'identifiant non valides sur "staging.name"
Il y a deux façons de faire ce que vous essayez
One is a Mise à jour corrélée multi-colonnes
UPDATE PRODUCTION a
SET (name, count) = (
SELECT name, count
FROM STAGING b
WHERE a.ID = b.ID);
Vous pouvez utiliser merge
MERGE INTO PRODUCTION a
USING ( select id, name, count
from STAGING ) b
ON ( a.id = b.id )
WHEN MATCHED THEN
UPDATE SET a.name = b.name,
a.count = b.count
Sans des exemples de l'ensemble de données sur la mise en scène, c'est un coup dans le noir, mais avez-vous déjà essayé quelque chose comme ça?
update PRODUCTION p,
staging s
set p.name = s.name
p.count = s.count
where p.id = s.id
Cela fonctionnerait en supposant que la colonne id corresponde aux deux tables.
Essayez-le ..
UPDATE PRODUCTION a
SET (name, count) = (
SELECT name, count
FROM STAGING b
WHERE a.ID = b.ID)
WHERE EXISTS (SELECT 1
FROM STAGING b
WHERE a.ID=b.ID
);
Comme vous l'avez remarqué, votre déclaration de mise à jour n'est pas sélective, elle met donc à jour tout votre tableau. Si vous souhaitez mettre à jour des lignes spécifiques (c'est-à-dire où les ID correspondent), vous souhaiterez probablement effectuer une sous-requête coordonnée.
Cependant, puisque vous utilisez Oracle, il pourrait être plus facile de créer une vue matérialisée pour votre table de requêtes et de laisser le mécanisme de transaction d'Oracle gérer les détails. Les MV fonctionnent exactement comme une table pour interroger la sémantique, sont assez faciles à configurer et vous permettent de spécifier l’intervalle de rafraîchissement.