Wie kann ich in Oracle eine Einschränkung "nicht null" löschen, wenn ich den Namen der Einschränkung nicht kenne?

81

Ich habe eine Datenbank mit einer NOT NULL-Einschränkung für ein Feld und möchte diese Einschränkung entfernen. Der komplizierende Faktor ist, dass diese Einschränkung einen systemdefinierten Namen hat und der Name dieser Einschränkung zwischen dem Produktionsserver, dem Integrationsserver und den verschiedenen Entwicklerdatenbanken unterschiedlich ist. Unser aktueller Prozess ist das Einchecken von Änderungsskripten, und eine automatisierte Aufgabe führt die entsprechenden Abfragen über sqlplus für die Zieldatenbank aus. Daher würde ich eine Lösung bevorzugen, die direkt an sqlplus gesendet werden kann.

In meiner eigenen Datenbank wäre das SQL, um dies zu löschen, Folgendes:

alter table MYTABLE drop constraint SYS_C0044566

Ich kann die Einschränkung sehen, wenn ich die all_constraintsAnsicht abfrage :

select * from all_constraints where table_name = 'MYTABLE'

aber ich bin nicht sicher , wie man die Arbeit mit dem SEARCH_CONDITION‚s LONGDatentyp oder wie man am besten dynamisch löschen Sie die nachgeschlagenen up Zwang , auch nachdem ich seinen Namen kennen.

Wie kann ich also ein Änderungsskript erstellen, das diese Einschränkung basierend auf dem, was sie ist, und nicht auf dem Namen aufheben kann?


EDIT: @ Allans Antwort ist gut, aber ich bin besorgt (aufgrund meines Mangels an Oracle-Fachwissen), dass es möglicherweise nicht allgemein gültig ist, dass eine Einschränkung, die möglicherweise einen vom System generierten Namen hat, eine Möglichkeit zum Entfernen des Namens mit sich bringt Einschränkung, ohne den Namen kennen zu müssen. Stimmt es, dass es immer eine Möglichkeit gibt, zu vermeiden, dass der Name einer vom System benannten Einschränkung bekannt sein muss, wenn diese Einschränkung logisch gelöscht wird?

Chris Farmer
quelle
3
Nur um Ihre Neugier zu befriedigen: Die NOT NULL-Einschränkung ist der einzige Einschränkungstyp in Oracle, den Sie entfernen können, ohne den Namen der Einschränkung kennen zu müssen. Bei allen anderen Einschränkungstypen muss der Name der Einschränkung bekannt sein.
Jeffrey Kemp

Antworten:

162
alter table MYTABLE modify (MYCOLUMN null);

In Oracle werden automatisch keine Null-Einschränkungen erstellt, wenn für eine Spalte nicht null angegeben wird. Ebenso werden sie automatisch gelöscht, wenn die Spalte geändert wird, um Nullen zuzulassen.

Klärung der überarbeiteten Frage : Diese Lösung gilt nur für Einschränkungen, die für Spalten "nicht null" erstellt wurden. Wenn Sie in der Spaltendefinition "Primärschlüssel" oder eine Prüfbedingung angeben, ohne sie zu benennen, erhalten Sie einen vom System generierten Namen für die Einschränkung (und den Index für den Primärschlüssel). In diesen Fällen müssen Sie den Namen kennen, um ihn löschen zu können. Der beste Rat ist, das Szenario zu vermeiden, indem Sie sicherstellen, dass Sie einen Namen für alle Einschränkungen außer "nicht null" angeben. Wenn Sie sich in einer Situation befinden, in der Sie eine dieser Einschränkungen generisch aufheben müssen, müssen Sie wahrscheinlich auf PL / SQL und die Datendefinitionstabellen zurückgreifen.

Allan
quelle
Das scheint wirklich zu schön, um wahr zu sein, aber es behandelt definitiv meinen aktuellen Fall und ist einfach! Gibt es Fälle in Oracle, in denen der Einschränkungsname vom System generiert werden könnte, die SQL jedoch nicht geschrieben werden könnte, um den Einschränkungsnamen so zu vermeiden?
Chris Farmer
1
Danke ... es stellt sich heraus, dass not nullEinschränkungen die einzigen systemnamen in meinem Schema sind, die mich wahrscheinlich jemals auf diese Weise beeinflussen werden.
Chris Farmer
16

Versuchen:

alter table <your table> modify <column name> null;
Vasanth
quelle
1

Denken Sie daran, wenn das Feld, das Sie auf Null setzen möchten, Teil eines Primärschlüssels ist, können Sie dies nicht. Primärschlüssel dürfen keine Nullfelder haben.

Mary C.
quelle
1

Verwenden Sie den folgenden Code, um die verwendeten Einschränkungen zu ermitteln:

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

Dies zeigt im Wesentlichen eine create-Anweisung für die Erstellung der referenzierten Tabelle. Wenn Sie wissen, wie die Tabelle erstellt wird, können Sie alle Tabelleneinschränkungen anzeigen.

Antwort aus Michael McLaughlins Blog: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ Aus seiner Klasse Database Design I.

FrostyDog
quelle
0

Ich hatte das gleiche Problem beim Versuch, eine benutzerdefinierte Überprüfungsbeschränkung zu umgehen, die ich aktualisieren musste, um unterschiedliche Werte zuzulassen. Das Problem ist, dass ALL_CONSTRAINTS nicht erkennen kann, auf welche Spalte die Einschränkung (en) angewendet werden. Ich habe es geschafft, indem ich stattdessen ALL_CONS_COLUMNS abgefragt habe, dann jede der Einschränkungen nach ihrem Namen gelöscht und neu erstellt habe.

Wählen Sie den Einschränkungsnamen aus all_cons_columns aus, wobei table_name = [TABLE_NAME] und column_name = [COLUMN_NAME];

CaduMaciel
quelle
0

So etwas ist mir passiert, als ich Kopien von Strukturen in temporäre Tabellen erstellt habe, also habe ich die Nicht-Null entfernt.

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;
Francisco
quelle
Stack Overflow ist eine reine englische Site. Es gibt jedoch einen Stapelüberlauf en español . Siehe meine Bearbeitung.
help-info.de
0

Wenn beim Erstellen einer Tabelle eine Einschränkung für die Spalte STATUS ohne Namen erstellt wurde, weist Oracle ihr einen zufälligen Namen zu. Leider können wir die Einschränkung nicht direkt ändern.

Schritte zum Löschen einer unbenannten Einschränkung, die mit der Spalte STATUS verknüpft ist

  1. Duplizieren Sie das STATUS-Feld in ein neues Feld STATUS2
  2. Definieren Sie CHECK-Einschränkungen für STATUS2
  3. Migrieren Sie Daten von STATUS nach STATUS2
  4. Spalte STATUS löschen
  5. Benennen Sie STATUS2 in STATUS um

    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;

Lukasz Ciesluk
quelle