He comprobado la documentación proporcionada por Oracle y encontró una manera de modificar una restricción sin que se caiga de la mesa. El problema es, que los errores en modificar ya que no reconoce la palabra clave.

El uso de EMS SQL Manager for PostgreSQL.

Alter table public.public_insurer_credit MODIFY CONSTRAINT public_insurer_credit_fk1
    deferrable, initially deferred;

Yo era capaz de trabajar alrededor de ella se quita la restricción de uso :

ALTER TABLE "public"."public_insurer_credit"
  DROP CONSTRAINT "public_insurer_credit_fk1" RESTRICT;

ALTER TABLE "public"."public_insurer_credit"
  ADD CONSTRAINT "public_insurer_credit_fk1" FOREIGN KEY ("branch_id", "order_id", "public_insurer_id")
    REFERENCES "public"."order_public_insurer"("branch_id", "order_id", "public_insurer_id")
    ON UPDATE CASCADE
    ON DELETE NO ACTION
    DEFERRABLE 
    INITIALLY DEFERRED;
  • ¿Por qué te comprobación de la documentación de Oracle (y etiquetar a esta pregunta con ‘plsql’) cuando usted está usando PostgreSQL? ¿Cuál es el error exacto (que la palabra clave no es reconocido)?
  • ERROR: ERROR de sintaxis en o cerca de «MODIFICAR» de la LÍNEA 1: Alter table público.public_insurer_credit MODIFICAR la RESTRICCIÓN de p… ^ (0.359 seg.)
  • La comprobación de Oracle docs para Postgres, y luego culpar a Postgres. Épica.
  • Yo era un noob y comprobación de la documentación que me fue proporcionada. Nunca se me ocurrió que el DBA me iba a dar el mal de la documentación. El comentario fue merecido.

4 Comentarios

  1. 33

    De acuerdo con el manual correcto (la cual es suministrada por PostgreSQL, no por Oracle), no es necesario modificar la restricción disponible en la instrucción ALTER TABLE:

    Aquí está el enlace para el manual correcto:

    http://www.postgresql.org/docs/current/static/sql-altertable.html

    • Gracias por el enlace a la documentación apropiada. Yo se suministra con el Oracle PL/SQL documentación de nuestro DBA. Las cifras.
    • Oracle y Oracle PL/SQL son cosas completamente diferentes. La única razón posible de que hizo eso es porque usted está utilizando EnterpriseDB Advanced Server, que tiene soporte para Oracle PL/SQL (y otros Oracle características de compatibilidad). Pero entonces se habría dado la EnterpriseDB manual, no el Oráculo manual
    • ¿Alguien puede explicar por qué esta respuesta obtuvo un downvote?
    • Mejor conjetura en downvote, la respuesta simplemente enlaces a un sitio externo, sin brindar a los futuros lectores una explicación de cómo una restricción puede ser cambiado correctamente.
  2. 81

    No hay ALTER comando para las restricciones en Postgres. La forma más sencilla de lograr esto es gota la restricción y volver a añadirlo con los parámetros deseados. Por supuesto, cualquier cambio de la restricción se ejecute en contra de la corriente de datos de tabla.

    BEGIN;
    ALTER TABLE t1 DROP CONSTRAINT ...
    ALTER TABLE t1 ADD CONSTRAINT ...
    COMMIT;
    • +1 para hacerlo en una transacción.
    • Tenga cuidado: si he entendido bien, las instrucciones DDL tomar un AccessExclusive bloqueo en la tabla, por lo que si estos comandos tomar un largo tiempo, su sitio se detendrán hasta que los comandos completa. El página de documentación tiene más detalles, incluyendo cómo especificar un índice de forma explícita, en lugar de tener un solo genera automáticamente.
    • Una sola transacción es bueno. Un solo comando es aún mejor. Ejemplo: stackoverflow.com/a/31419767/939860
  3. 31

    A partir de la versión 9.4, PostgreSQL soporta ALTER TABLE ... ALTER CONSTRAINT para claves foráneas.

    Esta características "Allow constraint attributes to be altered,
    so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back."
    Mirando a su pregunta creo que es (tipo de) lo que usted ha estado buscando.

    Información más detallada y un ejemplo puede ser encontrado aquí:

    http://www.depesz.com/2013/06/30/waiting-for-9-4-alter-table-alter-constraint-for-fks/

  4. 5

    ALTERAR RESTRICCIÓN requieren un conocimiento de la clave externa nombre, que no siempre es conveniente.

    Aquí es la función, donde usted necesita saber sólo nombres de tabla y columna.
    Uso:

    select replace_foreign_key('user_rates_posts', 'post_id', 'ON DELETE CASCADE');

    Función:

    CREATE OR REPLACE FUNCTION 
        replace_foreign_key(f_table VARCHAR, f_column VARCHAR, new_options VARCHAR) 
    RETURNS VARCHAR
    AS $$
    DECLARE constraint_name varchar;
    DECLARE reftable varchar;
    DECLARE refcolumn varchar;
    BEGIN
    
    SELECT tc.constraint_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name 
    FROM 
        information_schema.table_constraints AS tc 
        JOIN information_schema.key_column_usage AS kcu
          ON tc.constraint_name = kcu.constraint_name
        JOIN information_schema.constraint_column_usage AS ccu
          ON ccu.constraint_name = tc.constraint_name
    WHERE constraint_type = 'FOREIGN KEY' 
       AND tc.table_name= f_table AND kcu.column_name= f_column
    INTO constraint_name, reftable, refcolumn;
    
    EXECUTE 'alter table ' || f_table || ' drop constraint ' || constraint_name || 
    ', ADD CONSTRAINT ' || constraint_name || ' FOREIGN KEY (' || f_column || ') ' ||
    ' REFERENCES ' || reftable || '(' || refcolumn || ') ' || new_options || ';';
    
    RETURN 'Constraint replaced: ' || constraint_name || ' (' || f_table || '.' || f_column ||
     ' -> ' || reftable || '.' || refcolumn || '); New options: ' || new_options;
    
    END;
    $$ LANGUAGE plpgsql;

    Ser consciente: esta función no copia atributos de la inicial de la clave externa.
    Sólo toma exterior nombre de la tabla /nombre de la columna, las gotas de la clave actual y reemplaza con uno nuevo.

    • Solución muy interesante

Dejar respuesta

Please enter your comment!
Please enter your name here