I
I had a legacy table with unique key but without primary key. All columns were mandatory and there was no reason to not have a proper primary key. First, lets's check list of unique keys.
SELECT c.table_name, c.constraint_name, LISTAGG(c.column_name, ', ') WITHIN GROUP (ORDER BY c.position) AS cols FROM user_constraints n JOIN user_cons_columns c ON c.constraint_name = n.constraint_name WHERE n.table_name = '&TABLE_NAME' AND n.constraint_type = 'U' GROUP BY c.table_name, c.constraint_name ORDER BY c.table_name, c.constraint_name;
Script to switch UQ constraint to PK:
DECLARE in_uq_constraint CONSTANT VARCHAR2(30) := '&UQ_NAME'; in_pk_name CONSTANT VARCHAR2(30) := '&PK_NAME'; -- in_table_name VARCHAR2(30); in_primary_cols VARCHAR2(32767); q VARCHAR2(32767); BEGIN -- get table name and primary columns SELECT p.table_name, LISTAGG(p.column_name, ', ') WITHIN GROUP (ORDER BY p.position) INTO in_table_name, in_primary_cols FROM user_cons_columns p WHERE p.constraint_name = in_uq_constraint GROUP BY p.table_name; -- create list on new foreign keys FOR c IN ( SELECT 'ALTER TABLE ' || c.table_name || ' ADD CONSTRAINT ' || c.constraint_name || ' FOREIGN KEY (' || LISTAGG(c.column_name, ', ') WITHIN GROUP (ORDER BY c.position) || ')' || ' REFERENCES ' || in_table_name || ' (' || in_primary_cols || ')' AS q FROM user_constraints n JOIN user_cons_columns c ON c.constraint_name = n.constraint_name WHERE n.constraint_type = 'R' AND n.r_constraint_name = in_uq_constraint GROUP BY c.table_name ) LOOP DBMS_OUTPUT.PUT_LINE('-- BACKUP: ' || c.q || ';'); q := q || c.q || ';'; END LOOP; DBMS_OUTPUT.PUT_LINE('--'); -- drop existing foreign keys FOR c IN ( SELECT 'ALTER TABLE ' || RPAD(c.table_name, 30) || ' DROP CONSTRAINT ' || c.constraint_name AS q FROM user_constraints c WHERE c.constraint_type = 'R' AND c.r_constraint_name = 'UQ_DEPOT' ) LOOP DBMS_OUTPUT.PUT_LINE(c.q || ';'); END LOOP; -- drop and recreate original key DBMS_OUTPUT.PUT_LINE('--'); DBMS_OUTPUT.PUT_LINE( 'ALTER TABLE ' || RPAD(in_table_name, 30) || ' DROP CONSTRAINT ' || in_uq_constraint || ';' ); DBMS_OUTPUT.PUT_LINE( 'ALTER TABLE ' || RPAD(in_table_name, 30) || ' ADD CONSTRAINT ' || in_pk_name || ' PRIMARY KEY (' || in_primary_cols || ')' || ';' ); DBMS_OUTPUT.PUT_LINE('--'); -- recreate foreign keys from first step q := RTRIM(q, ';'); FOR c IN ( SELECT DISTINCT REGEXP_SUBSTR(q, '[^;]+', 1, LEVEL) AS q FROM DUAL CONNECT BY LEVEL <= REGEXP_COUNT(q, ';') + 1 ) LOOP DBMS_OUTPUT.PUT_LINE(c.q || ';'); END LOOP; END; /
Comments
Post a Comment