Cómo eliminar todas las restricciones NO NULAS de una tabla PostgreSQL de una sola vez
¿Es posible eliminar todas las restricciones NOT NULL de una tabla de una sola vez?
Tengo una gran tabla con muchas restricciones NO NULAS y estoy buscando una solución que sea más rápida que soltarlas por separado.
6 answers
Puedes agruparlos todos en la misma declaración alter:
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 do block 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 primaria, por lo que querrá filtrarlos.)
Si haces esto, no olvides usar quote_ident()
en el caso de que alguna vez necesites lidiar con personajes potencialmente extraños en los nombres de las columnas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-22 14:07:33
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:
SELECCIONE dropNull (TABLENAME);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-02 10:55:26
ALTER TABLE table_name ALTER COLUMN [SET NOT NULL / DROP NOT NULL]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-23 12:16:33
Hay un camino rápido y sucio 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 arruinas esto puedes terminar rompiendo tu sistema.
La regla básica es: nunca manipule directamente los catálogos del sistema.
La forma limpia solo necesita privilegios regulares para alterar la tabla: automatícela con SQL dinámico en una instrucció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
$$
Todavía muy rápido. Ejecutar tenga cuidado con los comandos dinámicos y tenga cuidado con la inyección SQL.
Este es un spin-off de esta respuesta más grande:
Generar valores PREDETERMINADOS en un CTE UPSERT usando PostgreSQL 9.3
Allí tenemos la necesidad de soltar restricciones NOT NULL de una tabla creada con:
CREATE TABLE tbl_b (LIKE tbl_a INCLUDING DEFAULTS);
Desde entonces, por documentación :
Las restricciones Not-null siempre se copian en la nueva tabla.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:12
Tuve un escenario que necesitaba eliminar el NOT NULL
de cada campo con un cierto nombre 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; $$;
A cuestas algunos otros ejemplos, esto funcionó mejor para mis necesidades
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-05 06:13:29
Sí, lo es. Yo tenía el mismo problema..
Para resolver, tuve que escribir un script C#. net que atravesaba toda la base de datos plSql y eliminaba todas las restricciones coincidentes..
Para obtener información específica sobre cómo eliminar restricciones individuales, siga el enlace. http://www.techonthenet.com/oracle/foreign_keys/drop.php
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-22 13:53:02