Come posso eliminare un vincolo "non nullo" in Oracle quando non conosco il nome del vincolo?


85

Ho un database che ha un vincolo NOT NULL su un campo e desidero rimuovere questo vincolo. Il fattore complicante è che questo vincolo ha un nome definito dal sistema e il nome di quel vincolo è diverso tra il server di produzione, il server di integrazione e i vari database degli sviluppatori. Il nostro processo attuale consiste nell'archiviare gli script di modifica e un'attività automatizzata esegue le query appropriate tramite sqlplus sul database di destinazione, quindi preferirei una soluzione che potrebbe essere inviata direttamente a sqlplus.

Sul mio database, l'SQL per eliminare questo sarebbe:

alter table MYTABLE drop constraint SYS_C0044566

Posso vedere il vincolo quando interrogo la all_constraintsvista:

select * from all_constraints where table_name = 'MYTABLE'

ma non sono sicuro di come il lavoro con la SEARCH_CONDITION's LONGtipo di dati o il modo migliore per eliminare in modo dinamico il vincolo guardato-up anche dopo che io so il suo nome.

Quindi, come posso creare uno script di modifica che possa eliminare questo vincolo in base a ciò che è, piuttosto che al suo nome?


EDIT: la risposta di @ Allan è buona, ma sono preoccupato (nella mia mancanza di esperienza Oracle) che potrebbe non essere universalmente vero che qualsiasi vincolo che potrebbe avere un nome generato dal sistema avrà associato ad esso un modo per rimuovere il vincolo senza dover conoscere il suo nome. È vero che ci sarà sempre un modo per evitare di dover conoscere il nome di un vincolo con nome di sistema quando si elimina logicamente quel vincolo?


3
Solo per soddisfare la tua curiosità: il vincolo NOT NULL è l' unico tipo di vincolo in Oracle che puoi rimuovere senza bisogno di conoscere il nome del vincolo. Tutti gli altri tipi di vincolo è necessario conoscere il nome del vincolo.
Jeffrey Kemp,

Risposte:


170
alter table MYTABLE modify (MYCOLUMN null);

In Oracle, i vincoli not null vengono creati automaticamente quando non viene specificato null per una colonna. Allo stesso modo, vengono eliminati automaticamente quando la colonna viene modificata per consentire i valori nulli.

Chiarimento della domanda rivista : questa soluzione si applica solo ai vincoli creati per le colonne "non nulle". Se specifichi "Chiave primaria" o un vincolo di controllo nella definizione della colonna senza nominarla, ti ritroverai con un nome generato dal sistema per il vincolo (e l'indice, per la chiave primaria). In quei casi, dovresti conoscere il nome per rilasciarlo. Il miglior consiglio è quello di evitare lo scenario assicurandosi di specificare un nome per tutti i vincoli diverso da "non nullo". Se ti trovi nella situazione in cui devi eliminare uno di questi vincoli genericamente, probabilmente dovrai ricorrere a PL / SQL e alle tabelle di definizione dei dati.


Sembra davvero troppo bello per essere vero, ma risolve definitivamente il mio caso attuale ed è chiaramente semplice! Ci sono casi in Oracle in cui il nome del vincolo potrebbe essere generato dal sistema ma non è stato possibile scrivere sql per evitare il nome del vincolo in questo modo?
Chris Farmer

1
Grazie ... si scopre che i not nullvincoli sono gli unici con nome di sistema nel mio schema che probabilmente mi influenzeranno in questo modo.
Chris Farmer

16

Provare:

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

1

Ricorda, se il campo che vuoi rendere annullabile fa parte di una chiave primaria, non puoi. Le chiavi primarie non possono avere campi nulli.


1

Per scoprire eventuali vincoli utilizzati, utilizzare il codice seguente:

-- 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;

Questo mostra essenzialmente un'istruzione create per come viene creata la tabella di riferimento. Sapendo come viene creata la tabella, puoi vedere tutti i vincoli della tabella.

Risposta presa dal blog di Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ Dalla sua classe Database Design I.


0

Stavo affrontando lo stesso problema cercando di aggirare un vincolo di controllo personalizzato che dovevo aggiornare per consentire valori diversi. Il problema è che ALL_CONSTRAINTS non ha un modo per dire a quale colonna vengono applicati i vincoli. Il modo in cui sono riuscito a farlo è interrogando invece ALL_CONS_COLUMNS, quindi eliminando ciascuno dei vincoli con il loro nome e ricreandolo.

seleziona nome_vincolo da all_cons_colonne dove nome_tabella = [TABLE_NAME] e nome_colonna = [COLUMN_NAME];


0

Qualcosa del genere mi è successo quando ho fatto copie di strutture su tabelle temporanee, quindi ho rimosso il non null.

DECLARE
   CURSOR cur_temp_not_null IS
        SELECT table_name, constraint_name  FROM all_constraints WHERE table_name LIKE 'TEMP_%' AND  owner='myUSUARIO';

   V_sql VARCHAR2(200); 

BEGIN
  FOR c_not_null IN cur_temp_not_null
   LOOP
     v_sql :='ALTER TABLE ' || c_not_null.table_name || ' DROP CONSTRAINT '|| c_not_null.constraint_name;
     EXECUTE IMMEDIATE  v_sql;     
  END LOOP;
END;

Stack Overflow è un sito solo in inglese. Tuttavia, esiste Stack Overflow in spagnolo . Vedi la mia modifica.
help-info.de

0

Se il vincolo sulla colonna STATUS è stato creato senza un nome durante la creazione di una tabella, Oracle le assegnerà un nome casuale. Sfortunatamente, non possiamo modificare direttamente il vincolo.

Passaggi coinvolti nell'eliminazione del vincolo senza nome collegato alla colonna STATUS

  1. Duplica il campo STATUS in un nuovo campo STATUS2
  2. Definire i vincoli CHECK su STATUS2
  3. Migrare i dati da STATUS a STATUS2
  4. Elimina la colonna STATUS
  5. Rinomina STATUS2 in STATUS

    ALTER TABLE MY_TABLE ADD STATUS2 NVARCHAR2(10) DEFAULT 'OPEN'; ALTER TABLE MY_TABLE ADD CONSTRAINT MY_TABLE_CHECK_STATUS CHECK (STATUS2 IN ('OPEN', 'CLOSED')); UPDATE MY_TABLE SET STATUS2 = STATUS; ALTER TABLE MY_TABLE DROP COLUMN STATUS; ALTER TABLE MY_TABLE RENAME COLUMN STATUS2 TO STATUS;

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.