una tipo tabla reemplazar quitar postgres por not modificar drop dato constraint como columna campo cambiar alterar agregar sql postgresql constraints sql-drop notnull

tipo - Cómo eliminar todas las restricciones NOT NULL de una tabla PostgreSQL de una sola vez



quitar not null postgresql (6)

ALTER TABLE table_name ALTER COLUMN [SET NOT NULL | GOTA NO NULA]

¿Es posible eliminar todas las restricciones NOT NULL de una tabla de una sola vez?

Tengo una gran mesa con muchas restricciones NO NULAS y estoy buscando una solución que sea más rápida que eliminarlas por separado.


Hay una forma rápida y sucia con privilegios de superusuario :

UPDATE pg_attribute SET attnotnull = FALSE WHERE attrelid = ''tbl_b''::regclass -- schema-qualify if needed! AND attnotnull AND NOT attisdropped AND attnum > 0;

El atajo es tentador. Pero si lo arruinas puede terminar rompiendo tu sistema.
La regla básica es: nunca manipular directamente los catálogos del sistema.

La forma limpia solo necesita privilegios regulares para alterar la tabla: automatízalo con SQL dinámico en una declaración DO (esto implementa lo que Denis ya sugirió ):

DO $$ BEGIN EXECUTE ( SELECT ''ALTER TABLE tbl_b ALTER '' || string_agg (quote_ident(attname), '' DROP NOT NULL, ALTER '') || '' DROP NOT NULL'' FROM pg_catalog.pg_attribute WHERE attrelid = ''tbl_b''::regclass AND attnotnull AND NOT attisdropped AND attnum > 0 ); END $$

Aún muy rápido. Ejecute la atención con comandos dinámicos y desconfíe de la inyección de SQL.

Esta es una consecuencia de esta gran respuesta:
Genere valores DEFAULT en un UPSTE CTE utilizando PostgreSQL 9.3

Ahí tenemos la necesidad de eliminar restricciones NOT NULL de una tabla creada con:

CREATE TABLE tbl_b (LIKE tbl_a INCLUDING DEFAULTS);

Desde, por documentación :

Las restricciones no nulas siempre se copian en la nueva tabla.


Puedes agruparlos a todos en la misma sentencia:

alter table tbl alter col1 drop not null, alter col2 drop not null, …

También puede recuperar la lista de columnas relevantes del catálogo si desea escribir un bloque do para generar el sql necesario. Por ejemplo, algo como:

select a.attname from pg_catalog.pg_attribute a where attrelid = ''tbl''::regclass and a.attnum > 0 and not a.attisdropped and a.attnotnull;

(Tenga en cuenta que esto también incluirá los campos relacionados con la clave principal, así que querrá filtrarlos).

Si haces esto, no te olvides de usar quote_ident() en caso de que necesites lidiar con caracteres potencialmente extraños en los nombres de las columnas.


Sí lo es. Tuve el mismo problema ..

Para resolverlo, tuve que escribir un script de C # .net que atravesaba toda la base de datos de plSql y eliminaba todas las restricciones correspondientes.

Para obtener información específica sobre cómo eliminar restricciones únicas, siga el enlace. http://www.techonthenet.com/oracle/foreign_keys/drop.php


Si desea eliminar todas las restricciones NOT NULL en PostreSQL, puede usar esta función:

CREATE OR REPLACE FUNCTION dropNull(varchar) RETURNS integer AS $$ DECLARE columnName varchar(50); BEGIN FOR columnName IN select a.attname from pg_catalog.pg_attribute a where attrelid = $1::regclass and a.attnum > 0 and not a.attisdropped and a.attnotnull and a.attname not in( SELECT pg_attribute.attname FROM pg_index, pg_class, pg_attribute WHERE pg_class.oid = $1::regclass AND indrelid = pg_class.oid AND pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = any(pg_index.indkey) AND indisprimary) LOOP EXECUTE ''ALTER TABLE '' || $1 ||'' ALTER COLUMN ''||columnName||'' DROP NOT NULL''; END LOOP; RAISE NOTICE ''Done removing the NOT NULL Constraints for TABLE: %'', $1; RETURN 1; END; $$ LANGUAGE plpgsql;

Tenga en cuenta que las claves primarias serán excluidas.

Entonces puedes llamarlo usando:

SELECT dropNull (TABLENAME);


Tuve un escenario que necesitaba eliminar el NOT NULL de cada campo con un nombre determinado en toda la base de datos. Aquí estaba mi solución. La cláusula where podría modificarse para manejar cualquier patrón de búsqueda que necesite.

DO $$ DECLARE row record; BEGIN FOR row IN ( SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE column_name IN ( ''field1'', ''field2'' ) ) LOOP EXECUTE ''ALTER TABLE '' || row.table_schema || ''.'' || row.table_name || '' ALTER '' || string_agg (quote_ident(row.column_name), '' DROP NOT NULL, ALTER '') || '' DROP NOT NULL;''; END LOOP; END; $$;

Junto a otros ejemplos, esto funcionó mejor para mis necesidades