Trying to modify a constraint in PostgreSQL

后端 未结 4 1510
伪装坚强ぢ
伪装坚强ぢ 2021-02-01 11:57

I have checked the documentation provided by Oracle and found a way to modify a constraint without dropping the table. Problem is, it errors out at modify as it does not recogn

4条回答
  •  情话喂你
    2021-02-01 12:48

    ALTER CONSTRAINT would require knowing of foreign key name, which is not always convenient.

    Here is function, where you need to know only table and column names. Usage:

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

    Function:

    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;
    

    Be aware: this function won't copy attributes of initial foreign key. It only takes foreign table name / column name, drops current key and replaces with new one.

提交回复
热议问题