2010-02-08 3 views
4

Je cherche un moyen d'altérer les données de manière non destructive. J'ai une table qui a des données qui ne devraient pas être éditées - ce sont les données de base. Je voudrais avoir des modifications de l'utilisateur sur ces données, mais afin de maintenir l'intégrité des données de base, j'ai créé une deuxième table qui est un miroir de la structure de la table principale.Quelle est la façon correcte d'avoir une vue des ajustements entre deux tables dans SQL

En pensant que je ferais fondamentalement une vue (vAdjustedData) telle que ces données sont UNIONed ensemble en me donnant une source qui était la version la plus à jour des données. (Le but de cette opération est de permettre aux utilisateurs d'annuler leurs données dans la table ajustée et d'avoir les données des tables principales restaurées pour être à jour).

Les colonnes des tables seront nulles. L'idée est que lorsqu'un utilisateur souhaite effectuer une modification, à ce moment-là, la fiche sera copiée, les modifications appliquées et enregistrées dans la table des ajustements. Mon idée pour un UNION masquerait la fiche d'origine avec l'enregistrement ajusté de telle sorte que, lorsqu'elle est placée dans une vue, j'obtiendrai les données "actuelles". Lorsque ce réglage est supprimé, la vue revient automatiquement.

J'ai donc Table_Master et Table_Adjusted. Table_Master a une clé primaire. Table_Adjusted possède également une clé primaire, mais c'est une clé étrangère à la clé primaire de Table_Master. Si les deux tables ont une colonne varchar j'attendre à écrire une vue qui était quelque chose de semblable à ceci:

(SELECT ID, Value 
FROM Table_Adjusted) 
UNION 
(SELECT ID, Value 
FROM Table_Master 
WHERE ID NOT IN (SELECT ID FROM Table_Adjusted)) 

L'UNION ci-dessus doit apporter toutes les valeurs ajustées et toutes les valeurs du maître qui n'a pas eu un enregistrement d'ajustement.

Est-ce la bonne façon de procéder? Pour moi, cela semble inefficace. Je pensais qu'un EXCEPT fonctionnerait (en utilisant SQL2K8) mais cela ne semblait pas approprié.

+0

Votre colonne Valeur est-elle valide? –

+0

Quelle sera la valeur dans la table ajustée, si une mise à jour n'a couvert que certaines colonnes? –

+0

Que se passe-t-il si la table ajustée contient un identifiant qui n'existe même pas dans la table principale? –

Répondre

2

Je suppose que vous voulez la table ajustée seulement régler valeurs et non ajouter ou supprimer valeurs. Votre requête a un inconvénient: il est théoriquement possible d'ajouter de nouvelles valeurs qui n'existent même pas dans la table d'origine. Cette version empêche ce risque possible:

SELECT Table_Master.ID, 
    CASE WHEN Table_Adjusted.ID IS NULL THEN Table_Master.Value 
     ELSE Table_Adjusted.Value 
    END AS Value 
FROM Table_Master 
LEFT JOIN Table_Adjusted 
ON Table_Master.ID = Table_Adjusted.ID 

également votre requête utilise un UNION DISTINCT mais vraiment vous avez seulement besoin UNION ALL. Cette version légèrement modifiée de votre requête devrait être légèrement plus rapide:

SELECT ID, Value 
FROM Table_Adjusted 
UNION ALL 
SELECT ID, Value 
FROM Table_Master 
WHERE ID NOT IN (SELECT ID FROM Table_Adjusted) 
+0

J'avais envisagé d'utiliser la jointure gauche et de faire CAS QUAND, mais j'ai pensé que l'UNION produirait des résultats plus rapides. Malheureusement, j'ai des champs nullables. La table ajustée ne modifierait que les valeurs qui apparaîtraient dans la table principale. –

+0

@Mike G: Ma deuxième requête gère le cas où la valeur est nullable. Je mettrai à jour ma réponse pour supprimer la première requête afin d'éviter toute confusion. –

+0

Maintenant que j'y pense, ce ne serait pas un LEFT OUTER JOIN?De cette façon, les tuples retournés seraient la valeur et ensuite un null. Pour les colonnes nullables je pourrais utiliser la vérification de cas et pour non-nullables l'opérateur COALESCE. Cependant, ma table du monde réel a beaucoup de colonnes de dénormalisation (pour éliminer les jointures) et la quantité d'ajustements n'est pas considérée comme grande. –

Questions connexes