O
On one of my projects I have to create patch scripts to add columns to a table or remove them. Thing is, that they might be run multiple times or might get different result on different environments.
So I created this simple script where I can define which column in which table I need to add or drop and it will skip what was already done. Keep in mind that I am not solving changed data types nor the column positions.
PROMPT PROCESSING TABLE CHANGES -- SET SERVEROUTPUT ON BEGIN FOR c IN ( WITH x (action, table_name, column_name, data_type) AS ( SELECT 'ADD', 'TABLE_NAME', 'COLUMN_NAME1', 'NUMBER' FROM DUAL UNION ALL SELECT 'DROP', 'TABLE_NAME', 'COLUMN_NAME2', NULL FROM DUAL ) SELECT x.*, c.column_name AS column_exists FROM x LEFT JOIN user_tab_cols c ON c.table_name = x.table_name AND c.column_name = x.column_name ) LOOP IF c.action = 'DROP' AND c.column_exists IS NOT NULL THEN EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' DROP COLUMN ' || c.column_name; DBMS_OUTPUT.PUT_LINE(' DROPPED ' || c.table_name || '.' || c.column_name); ELSIF c.action = 'ADD' AND c.column_exists IS NULL THEN EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' ADD ' || c.column_name || ' ' || c.data_type; DBMS_OUTPUT.PUT_LINE(' ADDED ' || c.table_name || '.' || c.column_name); END IF; END LOOP; END; /
After I change columns I like to move the audit columns to the bottom:
PROMPT MOVE AUDIT COLUMNS -- DECLARE in_table_name CONSTANT VARCHAR2(30) := '%'; in_columns CONSTANT VARCHAR2(4000) := 'CREATED_BY,CREATED_AT,UPDATED_BY,UPDATED_AT'; -- list audit columns BEGIN FOR t IN ( SELECT t.table_name FROM user_tables t LEFT JOIN user_mviews m ON m.mview_name = t.table_name WHERE t.table_name LIKE UPPER(in_table_name) ESCAPE '\' AND m.mview_name IS NULL ) LOOP FOR c IN ( WITH x AS ( SELECT LEVEL AS r#, UPPER(REGEXP_SUBSTR(in_columns, '[^,]+', 1, LEVEL)) AS column_name FROM DUAL CONNECT BY LEVEL <= REGEXP_COUNT(in_columns, ',') + 1 ) SELECT c.table_name, c.column_name FROM user_tab_cols c JOIN x ON x.column_name = c.column_name WHERE c.table_name = t.table_name ORDER BY x.r# ASC ) LOOP DBMS_OUTPUT.PUT_LINE(' MOVING ' || c.table_name || '.' || c.column_name); EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' MODIFY ' || c.column_name || ' INVISIBLE'; EXECUTE IMMEDIATE 'ALTER TABLE ' || c.table_name || ' MODIFY ' || c.column_name || ' VISIBLE'; END LOOP; END LOOP; END; /
Comments
Post a Comment