2010-03-29 6 views
62

J'ai une base de données qui a une contrainte NOT NULL sur un champ, et je veux supprimer cette contrainte. Le facteur de complication est que cette contrainte a un nom défini par le système, et que le nom de la contrainte diffère entre le serveur de production, le serveur d'intégration et les différentes bases de données des développeurs. Notre processus actuel consiste à vérifier les scripts de modification, et une tâche automatisée exécute les requêtes appropriées via sqlplus par rapport à la base de données cible, donc je préférerais une solution qui pourrait simplement être envoyée directement dans sqlplus.Comment puis-je supprimer une contrainte "non nulle" dans Oracle lorsque je ne connais pas le nom de la contrainte?

Sur ma propre base de données, le SQL de laisser tomber ce serait:

alter table MYTABLE drop constraint SYS_C0044566 

je peux voir la contrainte quand j'Interrogez la vue all_constraints:

select * from all_constraints where table_name = 'MYTABLE' 

mais je ne suis pas sûr de savoir comment fonctionne avec le type de données LONGSEARCH_CONDITION ou la meilleure façon de supprimer dynamiquement la contrainte recherchée même après que je connais son nom. Donc, comment puis-je créer un script de changement qui peut supprimer cette contrainte en fonction de ce qu'elle est, plutôt que de son nom?


EDIT: @ La réponse d'Allan est un bon, mais je suis préoccupé (à mon manque d'expertise Oracle) qu'il ne peut pas être universellement vrai que toute contrainte qui pourrait avoir un nom généré par le système aura associé à un moyen de supprimer la contrainte sans avoir à connaître son nom. Est-il vrai qu'il y aura toujours un moyen d'éviter de connaître le nom d'une contrainte nommée par le système lors de la suppression logique de cette contrainte?

+3

Juste pour satisfaire votre curiosité: La contrainte NOT NULL est le type de contrainte * only * dans Oracle que vous pouvez supprimer sans avoir besoin de connaître le nom de la contrainte. Tous les autres types de contraintes dont vous avez besoin pour connaître le nom de la contrainte. –

Répondre

132
alter table MYTABLE modify (MYCOLUMN null); 

Dans Oracle, les contraintes non nulles sont créées automatiquement lorsque null n'est spécifié pour une colonne. De même, ils sont supprimés automatiquement lorsque la colonne est modifiée pour autoriser les valeurs NULL.

Clarification de la question révisée: Cette solution ne s'applique qu'aux contraintes créées pour les colonnes "non nulles". Si vous spécifiez "Clé primaire" ou une contrainte de vérification dans la définition de colonne sans la nommer, vous obtiendrez un nom généré par le système pour la contrainte (et l'index, pour la clé primaire). Dans ce cas, vous devez connaître le nom pour le supprimer. Le meilleur conseil est d'éviter le scénario en vous assurant de spécifier un nom pour toutes les contraintes autres que "not null". Si vous vous trouvez dans la situation où vous devez supprimer l'une de ces contraintes de manière générique, vous devrez probablement utiliser PL/SQL et les tables de définition de données.

+0

Cela semble vraiment trop beau pour être vrai, mais il gère définitivement mon cas actuel et est tout simplement simple! Y a-t-il des cas dans Oracle où le nom de la contrainte pourrait être généré par le système mais le sql n'a pas pu être écrit pour éviter le nom de la contrainte comme ça? –

+1

Merci ... il s'avère que les contraintes 'non nulles 'sont les seules contraintes système de mon schéma susceptibles de m'affecter de cette façon. –

14

Essayez:

alter table <your table> modify <column name> null; 
+0

Cela fonctionne. Merci –

1

Rappelez-vous simplement, si le champ que vous voulez faire annulable fait partie d'une clé primaire, vous ne pouvez pas. Les clés primaires ne peuvent pas avoir de champs null.

0

Je faisais face au même problème en essayant de contourner une contrainte de vérification personnalisée que j'avais besoin de mettre à jour pour permettre différentes valeurs. Le problème est que ALL_CONSTRAINTS n'a aucun moyen de dire à quelle colonne les contraintes sont appliquées. La façon dont j'ai réussi à le faire est en interrogeant ALL_CONS_COLUMNS à la place, puis en supprimant chacune des contraintes par leur nom et en les recréant.

select constraint_name de all_cons_columns où table_name = [TABLE_NAME] et column_name = [COLUMN_NAME];

1

Pour découvrir toutes les contraintes utilisées, utilisez le code ci-dessous:

-- Set the long data type for display purposes to 500000. 

SET LONG 500000 

-- Define a session scope variable. 

VARIABLE output CLOB 

-- Query the table definition through the <code>DBMS_METADATA</code> package. 

SELECT dbms_metadata.get_ddl('TABLE','[Table Described]') INTO :output FROM dual; 

Cela montre essentiellement une instruction create de la façon dont est fait la table référencée. En sachant comment la table est créée, vous pouvez voir toutes les contraintes de la table.

Réponse tirée du blog de Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ De sa classe Database Design I.

Questions connexes