2008-11-20 16 views
3

Le programme auquel je suis actuellement affecté a l'obligation de copier le contenu d'une table dans une table de sauvegarde, avant le traitement réel.Oracle Remplir la table de sauvegarde de la table primaire

Au cours de l'examen du code, un collègue de travail a souligné que

INSERT INTO BACKUP_TABLE 
SELECT * 
FROM PRIMARY_TABLE 

est trop risqué, car il est possible que les tables ont des colonnes et des commandes de colonnes différentes.

Je suis également sous la contrainte de ne pas créer/supprimer/renommer des tables. ~ Sigh ~

Il est prévu que les colonnes du tableau changent, donc le simple fait de coder en dur les noms de colonne n'est pas vraiment la solution que je recherche.

Je cherche des idées sur une façon raisonnable et non-risquée de faire ce travail.

Répondre

7

La table de sauvegarde reste-t-elle ouverte? Conserve-t-il les données de façon permanente ou s'agit-il simplement d'une copie des valeurs actuelles?

Dommage de ne pas pouvoir créer/supprimer/renommer/copier. Dans le cas contraire, si elle est à court terme, juste utilisé dans le cas où quelque chose va mal, vous pouvez le déposer au début du traitement et de faire quelque chose comme

create table backup_table as select * from primary_table; 

Votre meilleure option peut être de faire la sélection explicite, comme

Vous pouvez générer cela en créant une chaîne SQL à partir du dictionnaire de données, puis en exécutant l'exécution immédiate. Mais vous serez toujours à risque si la table backup_table ne contient pas toutes les colonnes importantes de la table primary_table. Peut vouloir juste le rendre explicite, et déclencher une erreur majeure si backup_table n'existe pas, ou l'une des colonnes dans primary_table ne sont pas dans backup_table.

+0

C'est permanent, et je ne suis pas autorisé à le créer. Ce serait beaucoup trop facile de cette façon. L'idée du dictionnaire de données semble viable. Voir quelles colonnes ils ont en commun et travailler avec ça. – EvilTeach

+0

Je suis allé avec l'option de dictionnaire de données. – EvilTeach

0

Vous pouvez essayer quelque chose comme:

CREATE TABLE secondary_table AS SELECT * FROM primary_table; 

Je ne sais pas si ces données copie automatiquement. Dans le cas contraire:

CREATE TABLE secondary_table AS SELECT * FROM primary_table LIMIT 1; 
INSERT INTO secondary_table SELECT * FROM primary_table; 

Edit:

Désolé, n'a pas lu votre message complètement: en particulier la partie des contraintes. J'ai peur de ne pas savoir comment. Ma conjecture serait d'utiliser une procédure qui décrit d'abord les deux tables et les compare, avant de créer une longue requête d'insertion/sélection.

Néanmoins, si vous utilisez une table de sauvegarde, je pense qu'il est très important qu'elle corresponde exactement à l'original.

+0

Je suis également sous la contrainte de ne pas créer/supprimer/renommer les tables – EvilTeach

1

Y a-t-il une raison pour laquelle vous ne pouvez pas simplement lister les colonnes dans les tables? Alors

INSERT INTO backup_table(col1, col2, col3, ... colN) 
    SELECT col1, col2, col3, ..., colN 
    FROM primary_table 

Bien sûr, cela exige que vous revisitez le code lorsque vous modifiez la définition de l'une des tables pour déterminer si vous devez apporter des modifications de code, mais qui est généralement un petit prix à payer pour vous isoler de les différences dans l'ordre des colonnes, les différences dans les noms de colonnes et les différences irrécupérables dans les définitions de tables.

+0

Eh bien, le facteur de paresse mis à part les tables devrait changer, et il y a un désir d'éviter de changer le programme. Merci d'avoir signalé cela. – EvilTeach

2

À quelle fréquence changez-vous la structure de vos tables? Votre méthode devrait fonctionner correctement à condition que la structure ne change pas. Personnellement, je pense que vos administrateurs de base de données devraient vous fournir un mécanisme pour supprimer la table de sauvegarde et la recréer, comme une procédure stockée. Nous avions quelque chose de similaire à mon dernier travail pour tronquer certaines tables, puisque la troncature est souvent beaucoup plus rapide que DELETE FROM TABLE;.

+0

Cette idée semble viable. Je vais vérifier avec mes DBA. – EvilTeach

1

Si j'avais cette situation, je récupérerais les définitions de colonne pour les deux tables juste au début du problème. Ensuite, si elles étaient identiques, je procéderais avec le simple:

INSERT INTO BACKUP_TABLE 
SELECT * 
FROM PRIMARY_TABLE 

Si elles étaient différentes, j'Avancez seulement s'il n'y avait pas de colonnes critiques manquantes de la table de sauvegarde. Dans ce cas, j'utiliser ce formulaire pour la copie de sauvegarde:

INSERT INTO BACKUP_TABLE (<list of columns>) 
SELECT <list of columns> 
FROM PRIMARY_TABLE 

Mais je voudrais aussi vous soucier de ce qui se passerait si je simplement arrêté le programme avec une erreur, donc je pourrais même avoir un plan de sauvegarde où je utiliserait le second formulaire pour les colonnes qui se trouvent dans les deux tables, et également vider un fichier texte avec le PK et toutes les colonnes manquantes dans la sauvegarde. Consignez également une erreur même s'il semble que le programme s'est terminé normalement. De cette façon, vous pourriez récupérer les données si le pire est arrivé. Vraiment, c'est un symptôme de mauvais processus quelque part qui devrait être traité, mais la programmation défensive peut aider à en faire le problème de quelqu'un d'autre, pas le vôtre. S'ils ne remarquent pas le message d'erreur de journal qui leur indique le vidage de texte avec les colonnes manquantes, alors ce n'est pas votre faute. Mais, si vous ne codez pas défensivement, et le pire arrive, ce sera en partie de votre faute.

Questions connexes