¿Tiene Postgres alguna forma de decir ALTER TABLE foo ADD CONSTRAINT bar ...
que simplemente ignorará el comando si la restricción ya existe, para que no genere un error?Postgres: Agregar restricción si no existe
Respuesta
esto podría ayudar, aunque puede ser un poco de un truco sucio:
create or replace function create_constraint_if_not_exists (
t_name text, c_name text, constraint_sql text
)
returns void AS
$$
begin
-- Look for our constraint
if not exists (select constraint_name
from information_schema.constraint_column_usage
where table_name = t_name and constraint_name = c_name) then
execute constraint_sql;
end if;
end;
$$ language 'plpgsql'
Entonces llamar con:
SELECT create_constraint_if_not_exists(
'foo',
'bar',
'ALTER TABLE foo ADD CONSTRAINT bar CHECK (foobies < 100);')
Actualizado:
Según Webmut's answer a continuación sugiere:
ALTER TABLE foo DROP CONSTRAINT IF EXISTS bar;
ALTER TABLE foo ADD CONSTRAINT bar ...;
Eso es probablemente muy bien en su base de datos de desarrollo, o donde se sabe que se puede excluir a las aplicaciones que dependen de esta base de datos para una ventana de mantenimiento.
Pero si se trata de un entorno de producción animado vitalicio las 24 horas del día, 7 días a la semana, en realidad no es conveniente dejar caer las limitaciones de esta forma. Incluso durante unos pocos milisegundos, hay una breve ventana en la que ya no está aplicando su restricción que puede permitir que los valores erróneos se salgan. Eso puede tener consecuencias no deseadas que conducen a considerables costos comerciales en algún momento del camino.
puede ejecutar la consulta sobre pg_constraint
tabla para encontrar limitación existe o not.like:
SELECT 1 FROM pg_constraint WHERE conname = 'constraint_name'"
No se una opción 'IF EXISTS' para' DROP CONSTRAINT' pero, AFAIK, nada para 'ADD CONSTRAINT'. –
¿Los nombres de restricciones son locales en una tabla? ¿Qué sucede si hay dos tablas con una restricción llamada 'constraint_name'? – guettli
Sí, podría obtener falsos positivos si otra tabla tuviera el mismo nombre de restricción. Pero esta sigue siendo una solución decente si tienes el 100% de control sobre tu nombre. –
¿No sabes por qué tantas líneas de código?
- SELECCIONE "Columna1", "Columna2", "Columna3", recuento (estrella) DE dbo. "MiTabla" GRUPO POR "Columna1", "Columna2", "Columna3" TIENE conteo (*)> 1;
alter table dbo. Restricción de caída "MyTable" si existe "MyConstraint_Name";
ALTER TABLE dbo. "MyTable" ADD CONSTRAINT "MyConstraint_Name" UNIQUE ("Column1", "Column3", "Column2");
Una posible solución es simplemente usar DROP IF EXISTS antes de crear la nueva restricción.
ALTER TABLE foo DROP CONSTRAINT IF EXISTS bar;
ALTER TABLE foo ADD CONSTRAINT bar ...;
parece más fácil que intentar consultar INFORMATION_SCHEMA o catálogos, pero podría ser lento en grandes mesas ya que siempre recrea la restricción.
Editar 2015-07-13: Kev señaló en his answer que mi solución crea una ventana corta cuando la restricción no existe y no se está aplicando. Si bien esto es cierto, puede evitar dicha ventana con bastante facilidad envolviendo ambas declaraciones en una transacción.
Puede usar un manejador de excepciones dentro de un bloque de DO anónimo para capturar el error de objeto duplicado.
DO $$
BEGIN
BEGIN
ALTER TABLE foo ADD CONSTRAINT bar ... ;
EXCEPTION
WHEN duplicate_object THEN RAISE NOTICE 'Table constraint foo.bar already exists';
END;
END $$;
http://www.postgresql.org/docs/9.4/static/sql-do.htmlhttp://www.postgresql.org/docs/9.4/static/plpgsql-control-structures.html http://www.postgresql.org/docs/9.4/static/errcodes-appendix.html
Tuve que cambiar 'duplicate_object' por' duplicate_table' (código 42P07). Postgres 9.6 – volvpavl
limitaciones Creación puede ser una operación costosa en una tabla que contiene una gran cantidad de datos de las limitaciones por lo que no recomiendo que caen sólo para crear inmediatamente de nuevo inmediatamente después - sólo desea crear ese Lo una vez.
me eligieron para resolver este usando un bloque de código anónimo, muy similar a Mike Stankavich, sin embargo a diferencia de Mike (que coge un error) La primera vez que comprobar para ver si existe la restricción:
DO $$ BEGIN IF NOT EXISTS (SELECT constraint_schema , constraint_name FROM information_schema.check_constraints WHERE constraint_schema = 'myschema' AND constraint_name = 'myconstraintname' ) THEN ALTER TABLE myschema.mytable ADD CONSTRAINT myconstraintname CHECK (column <= 100); END IF; END$$;
- 1. ¿Cómo verificar si existe un usuario postgres?
- 2. Agregar al archivo si existe y crear si no
- 3. SQL Server: ¿Cómo agrego una restricción a una tabla existente pero solo si la restricción no existe?
- 4. Entidad Marco: actualizar entidad o agregar si no existe
- 5. MySQL: ¿Cómo agregar una columna si aún no existe?
- 6. Agregar http: // www. en el texto si no existe
- 7. Cómo agregar http: // si no existe en la URL?
- 8. .htaccess redirect - agregar automáticamente www. si no existe un subdominio
- 9. ¿Agregar una columna si no existe para todas las tablas?
- 10. ¿Cómo verificar si existe una restricción en el servidor Sql?
- 11. ALTER TABLE agregar restricción
- 12. Crear si no existe
- 13. Array.push() si no existe?
- 14. Agregar clave principal a la tabla PostgreSQL solo si no existe
- 15. Crear tabla si no existe desde mysqldump
- 16. Si no existe, salga + cmd
- 17. sql - inserte si no existe
- 18. Crear una carpeta si no existe
- 19. jQuery: añadir elemento DOM si no existe
- 20. ¿Existe alguna restricción especial en los comandos ejecutados por cron?
- 21. IntegrityError valor clave duplicado viola la restricción única - django/postgres
- 22. jQuery Tokeninput añadir, si no existe
- 23. Postgres Restricción única en dos columnas: Entero y booleano
- 24. SQL Server SI NO EXISTE ¿Uso?
- 25. Django: compruebe si ya existe un objeto antes de agregar
- 26. Postgresql: compruebe si existe el esquema
- 27. PostgreSQL crean tabla si no existe
- 28. Django create userprofile si no existe
- 29. mysql create view only si no existe
- 30. MySQL Seleccione otra fila si no existe
Creo que ''myconstraint'' debería ser' 'bar'' en tu último ejemplo. –
@denis - bien atrapado. Gracias. – Kev
Modificaría más esta respuesta para que la instrucción de ejecución sea 'ejecutar 'ALTER TABLE' || t_name || 'AGREGAR RESTRICCIÓN' || c_name || '' || constraint_sql; 'y llamar a la función se vería como' SELECT create_constraint_if_not_exists ('foo', 'bar', 'CHECK (foobies <100);'); '. Esto garantiza que no se puedan desordenar los argumentos en su restricción SQL porque están basados en los parámetros originales. –