¿Cómo puedo eliminar una restricción "no nula" en Oracle cuando no sé el nombre de la restricción?

85

Tengo una base de datos que tiene una restricción NOT NULL en un campo y quiero eliminar esta restricción. El factor de complicación es que esta restricción tiene un nombre definido por el sistema y el nombre de esa restricción difiere entre el servidor de producción, el servidor de integración y las diversas bases de datos de desarrolladores. Nuestro proceso actual es verificar los scripts de cambio, y una tarea automatizada ejecuta las consultas apropiadas a través de sqlplus contra la base de datos de destino, por lo que preferiría una solución que pudiera enviarse directamente a sqlplus.

En mi propia base de datos, el SQL para eliminar esto sería:

alter table MYTABLE drop constraint SYS_C0044566

Puedo ver la restricción cuando consulto la all_constraintsvista:

select * from all_constraints where table_name = 'MYTABLE'

pero no estoy seguro de cómo trabajar con el SEARCH_CONDITION's LONGtipo de datos o la mejor manera de eliminar la restricción dinámica mirado en marcha incluso después de que sé su nombre.

Entonces, ¿cómo puedo crear un script de cambio que pueda eliminar esta restricción en función de lo que es, en lugar de su nombre?


EDITAR: La respuesta de @ Allan es buena, pero me preocupa (en mi falta de experiencia en Oracle) que puede no ser universalmente cierto que cualquier restricción que pueda tener un nombre generado por el sistema se haya asociado con una forma de eliminar el restricción sin tener que saber su nombre. ¿Es cierto que siempre habrá una manera de evitar tener que saber el nombre de una restricción con nombre del sistema cuando se elimine lógicamente esa restricción?

Chris Farmer
fuente
3
Solo para satisfacer su curiosidad: la restricción NOT NULL es el único tipo de restricción en Oracle que puede eliminar sin necesidad de conocer el nombre de la restricción. Todos los demás tipos de restricciones necesitan conocer el nombre de la restricción.
Jeffrey Kemp

Respuestas:

166
alter table MYTABLE modify (MYCOLUMN null);

En Oracle, las restricciones no nulas se crean automáticamente cuando no se especifica nulo para una columna. Asimismo, se eliminan automáticamente cuando se cambia la columna para permitir valores nulos.

Aclarando la pregunta revisada : Esta solución solo se aplica a las restricciones creadas para columnas "no nulas". Si especifica "Clave principal" o una restricción de verificación en la definición de columna sin nombrarla, terminará con un nombre generado por el sistema para la restricción (y el índice, para la clave principal). En esos casos, necesitaría saber el nombre para eliminarlo. El mejor consejo que existe es evitar el escenario asegurándose de especificar un nombre para todas las restricciones que no sea "no nulo". Si se encuentra en una situación en la que necesita eliminar una de estas restricciones de forma genérica, probablemente deba recurrir a PL / SQL y las tablas de definición de datos.

Alano
fuente
Eso parece demasiado bueno para ser verdad, ¡pero definitivamente maneja mi caso actual y es claramente simple! ¿Hay algún caso en Oracle en el que el nombre de la restricción pueda ser generado por el sistema pero el sql no se pudo escribir para evitar el nombre de la restricción como ese?
Chris Farmer
1
Gracias ... resulta que las not nullrestricciones son las únicas con nombre de sistema en mi esquema que probablemente me afecten de esta manera.
Chris Farmer
16

Tratar:

alter table <your table> modify <column name> null;
vasanth
fuente
1

Solo recuerde, si el campo que desea convertir en anulable es parte de una clave principal, no puede hacerlo. Las claves primarias no pueden tener campos nulos.

María C
fuente
1

Para descubrir las restricciones utilizadas, utilice el siguiente código:

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

Esto esencialmente muestra una declaración de creación de cómo se hace la tabla referenciada. Al saber cómo se crea la tabla, puede ver todas las restricciones de la tabla.

Respuesta tomada del blog de Michael McLaughlin: http://michaelmclaughlin.info/db1/lesson-5-querying-data/lab-5-querying-data/ De su clase de Diseño de base de datos I.

FrostyDog
fuente
0

Estaba enfrentando el mismo problema al intentar sortear una restricción de verificación personalizada que necesitaba actualizar para permitir diferentes valores. El problema es que ALL_CONSTRAINTS no tiene una forma de saber a qué columna se aplican las restricciones. La forma en que logré hacerlo es consultando ALL_CONS_COLUMNS en su lugar, luego descartando cada una de las restricciones por su nombre y volviendo a crearlas.

seleccione nombre_restricción de all_cons_columns donde nombre_tabla = [TABLE_NAME] y column_name = [COLUMN_NAME];

CaduMaciel
fuente
0

Algo así me pasó cuando hice copias de estructuras en tablas temporales, así que eliminé el 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;
Francisco
fuente
Stack Overflow es un sitio solo en inglés. Sin embargo, hay Stack Overflow en español . Ver mi edición.
help-info.de
0

Si la restricción en el ESTADO de la columna se creó sin un nombre durante la creación de una tabla, Oracle le asignará un nombre aleatorio. Desafortunadamente, no podemos modificar la restricción directamente.

Pasos involucrados para eliminar la restricción sin nombre vinculada a la columna ESTADO

  1. Duplique el campo STATUS en un nuevo campo STATUS2
  2. Definir restricciones CHECK en STATUS2
  3. Migrar datos de STATUS a STATUS2
  4. Quitar columna ESTADO
  5. Cambiar el nombre de STATUS2 a 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;

Lukasz Ciesluk
fuente