webentwicklung-frage-antwort-db.com.de

Es wurde versucht, eine Einschränkung in PostgreSQL zu ändern

Ich habe die von Oracle bereitgestellte Dokumentation überprüft und eine Möglichkeit gefunden, eine Einschränkung zu ändern, ohne die Tabelle zu löschen. Das Problem ist, dass es Fehler beim Ändern gibt, da es das Schlüsselwort nicht erkennt.

Verwenden von EMS SQL Manager für PostgreSQL.

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

Ich konnte das Problem umgehen, indem ich die Einschränkung mit folgendem Befehl löschte:

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;

Gemäß dem richtigen Handbuch (das von PostgreSQL bereitgestellt wird, und nicht von Oracle) ist in der ALTER TABLE-Anweisung keine Änderungsbeschränkung verfügbar:

Hier ist der Link zum richtigen Handbuch:

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

34

Es gibt keinen ALTER Befehl für Einschränkungen in Postgres. Der einfachste Weg, dies zu erreichen, ist drop die Bedingung und fügen Sie sie mit den gewünschten Parametern erneut hinzu. Natürlich wird jede Änderung der Einschränkung für die aktuellen Tabellendaten ausgeführt.

BEGIN;
ALTER TABLE t1 DROP CONSTRAINT ...
ALTER TABLE t1 ADD CONSTRAINT ...
COMMIT;
82
Chris Cashwell

Ab Version 9.4 unterstützt PostgreSQL ALTER TABLE ... ALTER CONSTRAINT für Fremdschlüssel.

Diese Funktionen werden "Allow constraint attributes to be altered, so the default setting of NOT DEFERRABLE can be altered to DEFERRABLE and back." Wenn du deine Frage betrachtest, denke ich, dass das genau das ist, wonach du gesucht hast.

Nähere Informationen und ein Beispiel finden Sie hier:
http://www.depesz.com/2013/06/30/waiting-for-9-4-alter-table-alter-constraint-for-fks/

31
mkurz

ALTER CONSTRAINT würde die Kenntnis des Fremdschlüsselnamens erfordern, was nicht immer praktisch ist.

Hier ist die Funktion, bei der Sie nur Tabellen- und Spaltennamen kennen müssen. Verwendung:

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

Funktion:

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;

Beachten Sie: Diese Funktion kopiert Attribute des anfänglichen Fremdschlüssels nicht. Es werden nur fremde Tabellennamen/Spaltennamen verwendet, der aktuelle Schlüssel wird gelöscht und durch einen neuen ersetzt .

5