Y
You might be frustrated when you want to add a column to a table and you can't choose a specific position. You can't easily change column order either. Well, this is the best trick. Just change the position in dictionary without moving data, cloning or recreating a table. Or without using DBMS_REDEFINITION.
Move specific column to the end of the table:
DECLARE in_table_name CONSTANT user_tab_cols.table_name%TYPE := '&TABLE_NAME'; in_column_name CONSTANT user_tab_cols.column_name%TYPE := '&COLUMN_NAME'; BEGIN EXECUTE IMMEDIATE 'ALTER TABLE ' || in_table_name || ' MODIFY ' || in_column_name || ' INVISIBLE'; -- EXECUTE IMMEDIATE 'ALTER TABLE ' || in_table_name || ' MODIFY ' || in_column_name || ' VISIBLE'; END; /
To reorder all columns in desired order you need to provide a full list of colums. Here is how to get the current list:
SELECT LISTAGG(c.column_name, ',') WITHIN GROUP (ORDER BY c.column_id) AS columns FROM user_tab_cols c WHERE c.table_name = '&TABLE_NAME';
You can export data from this query for all tables in one environment and apply it on another env to keep tables same.
You manually alter this list according to your needs and pass it to this script:
DECLARE in_table_name CONSTANT user_tables.table_name%TYPE := '&TABLE_NAME'; in_columns CONSTANT VARCHAR2(32767) := '&COLUMNS'; -- COLUMN_NAME,COLUMN_NAME,COLUMN_NAME... BEGIN FOR c IN ( SELECT c.column_name FROM user_tab_cols c LEFT JOIN user_constraints n ON n.table_name = c.table_name AND n.constraint_type = 'P' -- skip primary key columns LEFT JOIN user_cons_columns l ON l.table_name = c.table_name AND l.column_name = c.column_name AND l.constraint_name = n.constraint_name WHERE c.table_name = in_table_name AND l.constraint_name IS NULL ORDER BY c.column_id DESC ) LOOP BEGIN EXECUTE IMMEDIATE 'ALTER TABLE ' || in_table_name || ' MODIFY ' || c.column_name || ' INVISIBLE'; EXCEPTION WHEN OTHERS THEN IF SQLCODE = -54039 THEN -- you need at least 1 column visible NULL; ELSE RAISE; END IF; END; END LOOP; -- FOR c IN ( SELECT d.column_name FROM ( SELECT REGEXP_REPLACE(REGEXP_SUBSTR(in_columns, '[^,]+', 1, LEVEL), '\s+', '') AS column_name, LEVEL AS column_id FROM DUAL CONNECT BY REGEXP_SUBSTR(in_columns, '[^,]+', 1, LEVEL) IS NOT NULL ) d JOIN user_tab_cols c ON c.table_name = in_table_name AND c.column_name = d.column_name ORDER BY d.column_id ) LOOP EXECUTE IMMEDIATE 'ALTER TABLE ' || in_table_name || ' MODIFY ' || c.column_name || ' VISIBLE'; -- DBMS_OUTPUT.PUT_LINE(c.column_name); END LOOP; END; /
Check invalid objects, recompile if needed and you are done.
Comments
Post a Comment