Y at-il quelque chose comme une « colonne symlink » dans Oracle?
-
26-10-2019 - |
Question
Je voudrais avoir une colonne dans mon DB accessible par deux noms de colonnes temporairement.
Pourquoi? Le nom de la colonne a été mal choisi, je voudrais refactoriser. Comme je veux que mon webapp reste stable tout en changeant le nom de la colonne, il serait bon de
- ont un (Appelons-le) lien symbolique nommé better_column_name pointant vers la colonne bad_column_name
- changer le webapplication utiliser better_column_name
- déposer la colonne et symlink renommage better_column_name
« Bases de données refactoring » suggère d'ajouter en fait une deuxième colonne qui est synchronisé lors de la validation afin d'y parvenir. J'espère juste qu'il pourrait y avoir un moyen plus facile avec Oracle, avec moins de travail et moins de frais généraux.
La solution
Tant que vous avez du code qui utilise les deux noms de colonnes, je ne vois pas un moyen de contourner le fait que vous aurez deux (vrais) colonnes dans ce tableau.
Je voudrais ajouter la nouvelle colonne avec le nom correct, puis créer un déclencheur qui vérifie que la colonne a été modifiée et met à jour la colonne « autres » en conséquence. Donc, tout ce qui est mis à jour, la valeur est synch'ed avec l'autre colonne.
Une fois que tout le code qui utilise l'ancienne colonne a été migré, retirez la gâchette et laisser tomber la vieille colonne.
Modifier
Le déclencheur aurait donc faire quelque chose comme ceci:
CREATE OR REPLACE TRIGGER ...
...
UPDATE OF bad_column_name, better_column_name ON the_table
...
BEGIN
IF UPDATING ('BAD_COLUMN_NAME') THEN
:new.better_column_name = :new.bad_column_name
END IF;
IF UPDATING ('BETTER_COLUMN_NAME') THEN
:new.bad_column_name = :new.better_column_name
END IF;
END;
L'ordre des déclarations de IF
contrôles qui changent a une « plus grande priorité » dans le cas où une personne a mis à jour les deux colonnes en même temps.
Autres conseils
Renommer la table:
alter table mytable rename to mytable_old;
Créer une vue avec la tablename originale à la fois bad_column_name et better_column_name qui pointent vers la même colonne (et bien sûr toutes les autres colonnes):
create or replace view mytable as
select column1
, column2
, ...
, bad_column_name
, bad_column_name better_column_name
from mytable_old
;
Depuis ce point de vue est actualisable par défaut (je suppose ici que matable a une clé primaire), vous pouvez insérer / mettre à jour / supprimer de la vue et il n'a pas d'importance si vous utilisez bad_column_name ou better_column_name.
Après le refactoring, laissez tomber la vue et renommer la table et la colonne:
drop view mytable;
alter table mytable_old rename column bad_column_name to better_column_name;
alter table mytable_old rename to mytable;
La meilleure solution est uniquement disponible dans la version 2 d'Oracle: Edition basée Redéfinition. Cette fonctionnalité vraiment cool nous permet de maintenir les différentes versions de tables de base de données et le code PL / SQL, en utilisant des déclencheurs spéciaux et points de vue. Pour en savoir plus .
Il s'agit essentiellement de la mise en œuvre d'Oracle intégré
vous pouvez créer une vue de la table. Et le port de votre application à utiliser ce point de vue au lieu de la table. create table t (bad_name varchar2(10), c2 varchar2(10));
create view vt as select bad_name AS good_name, c2 from t;
insert into vt (good_name, c2) values ('blub', 'blob');
select * from t;
select * from vt;
Si vous êtes sur vous 11g pourrait envisager d'utiliser une colonne virtuelle. Je serais probablement tenté de changer légèrement l'ordre; renommer la vraie colonne et créer le virtuel en utilisant l'ancien (mauvais) nom, qui peut ensuite être abandonné à loisir. Vous pouvez être limité, bien sûr, et il peut y avoir des répercussions sur d'autres objets invalidée qui rendent cet ordre moins approprié pour vous.