Как я могу отказаться от ограничения «не null» в Oracle, если я не знаю имени ограничения?


85

У меня есть база данных с ограничением NOT NULL для поля, и я хочу удалить это ограничение. Усложняющий фактор состоит в том, что это ограничение имеет системное имя, а имя этого ограничения различается между производственным сервером, сервером интеграции и различными базами данных разработчиков. Наш текущий процесс заключается в проверке сценариев изменений, а автоматическая задача выполняет соответствующие запросы через sqlplus к целевой базе данных, поэтому я бы предпочел решение, которое можно было бы просто отправить прямо в sqlplus.

В моей собственной базе данных SQL, чтобы удалить это, будет:

alter table MYTABLE drop constraint SYS_C0044566

Я вижу ограничение, когда запрашиваю all_constraintsпредставление:

select * from all_constraints where table_name = 'MYTABLE'

но я не знаю , как работать с SEARCH_CONDITIONLONG типом данных или как лучше динамически удалять смотрел вверх ограничение даже после того, как я знаю его имя.

Итак, как я могу создать сценарий изменения, который может снять это ограничение в зависимости от того, что это такое, а не от его имени?


РЕДАКТИРОВАТЬ: ответ @Allan является хорошим, но я обеспокоен (из-за моего отсутствия опыта в Oracle), что не всегда верно, что любое ограничение, которое может иметь сгенерированное системой имя, будет связано с ним способом удаления ограничение, не зная его имени. Верно ли, что всегда будет способ избежать необходимости знать имя ограничения, названного системой, при логическом удалении этого ограничения?


3
Просто чтобы удовлетворить ваше любопытство: ограничение NOT NULL - единственный тип ограничения в Oracle, который вы можете удалить, не зная имени ограничения. Для всех остальных типов ограничений вам необходимо знать имя ограничения.
Джеффри Кемп,

Ответы:


170
alter table MYTABLE modify (MYCOLUMN null);

В Oracle не пустые ограничения создаются автоматически, если для столбца указано ненулевое значение. Точно так же они автоматически удаляются, когда столбец изменяется, чтобы разрешить нули.

Уточнение пересмотренного вопроса : это решение применяется только к ограничениям, созданным для "ненулевых" столбцов. Если вы укажете «Первичный ключ» или проверочное ограничение в определении столбца без его имени, вы получите сгенерированное системой имя для ограничения (и индекс для первичного ключа). В таких случаях вам нужно знать имя, чтобы отказаться от него. Лучший совет - избежать такого сценария, убедившись, что вы указали имя для всех ограничений, кроме «not null». Если вы окажетесь в ситуации, когда вам нужно отказаться от одного из этих ограничений в целом, вам, вероятно, придется прибегнуть к PL / SQL и таблицам определения данных.


Это кажется слишком хорошим, чтобы быть правдой, но это определенно подходит для моего текущего случая и очень просто! Есть ли в оракуле случаи, когда имя ограничения может быть сгенерировано системой, но sql не может быть написан, чтобы избежать такого имени ограничения?
Крис Фармер,

1
Спасибо ... оказывается, что not nullограничения - единственные в моей схеме с системными именами, которые, вероятно, когда-либо повлияют на меня таким образом.
Крис Фармер,


1

Просто помните, что если поле, которое вы хотите сделать обнуляемым, является частью первичного ключа, вы не можете. Первичные ключи не могут иметь пустые поля.


1

Чтобы обнаружить любые используемые ограничения, используйте приведенный ниже код:

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

По сути, это показывает оператор create для создания указанной таблицы. Зная, как создается таблица, вы можете увидеть все ограничения таблицы.

Ответ взят из блога Майкла Маклафлина: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ Из его класса Database Design I.


0

Я столкнулся с той же проблемой, пытаясь обойти настраиваемое ограничение проверки, которое мне нужно было обновить, чтобы разрешить разные значения. Проблема в том, что ALL_CONSTRAINTS не может определить, к какому столбцу применяются ограничения. Мне удалось это сделать, запросив вместо этого ALL_CONS_COLUMNS, затем отбросив каждое из ограничений по их имени и воссоздав его.

выберите constraint_name из all_cons_columns, где table_name = [TABLE_NAME] и column_name = [COLUMN_NAME];


0

Что-то подобное случилось со мной, когда я сделал копии структур во временные таблицы, поэтому я удалил not 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 - это сайт только на английском языке. Однако есть Stack Overflow en español . Смотрите мою правку.
help-info.de

0

Если ограничение для столбца STATUS было создано без имени во время создания таблицы, Oracle присвоит ему случайное имя. К сожалению, мы не можем напрямую изменить ограничение.

Шаги, связанные с удалением безымянного ограничения, связанного со столбцом STATUS

  1. Дублировать поле STATUS в новое поле STATUS2
  2. Определите ограничения CHECK для STATUS2
  3. Перенести данные из STATUS в STATUS2
  4. Удалить столбец СТАТУС
  5. Переименуйте STATUS2 в 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;

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.