snippetMinor
How to replace a CLOB column by a varchar2(4000) column?
Viewed 0 times
howcolumnreplace4000varchar2clob
Problem
The following code seems to do the job, but I doubt, that it is robust enough.
How can I improve the code?
SET serveroutput on
DECLARE
v_isclob PLS_INTEGER;
v_cmd VARCHAR2(4000);
BEGIN
SELECT CASE when exists (select * from USER_TAB_COLUMNS where COLUMN_NAME = 'Column_to_modify' AND TABLE_NAME = 'MyTable' AND DATA_TYPE = 'CLOB') then 1 else 0 end into v_isclob FROM DUAL;
IF v_isclob > 0 THEN
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE MyTable RENAME COLUMN Column_to_modify TO XXX';
EXECUTE IMMEDIATE 'ALTER TABLE MyTable ADD Column_to_modify varchar2(4000)';
EXECUTE IMMEDIATE 'UPDATE MyTable SET Column_to_modify = SUBSTR(XXX, 1, 4000)';
EXECUTE IMMEDIATE 'ALTER TABLE MyTable DROP COLUMN XXX';
dbms_output.put_line ('++ Column_to_modify modified to varchar2(4000)');
EXCEPTION WHEN OTHERS THen
dbms_output.put_line ('##### Error while modifying Column_to_modify');
END;
else
dbms_output.put_line (' Column_to_modify is varchar(4000)');
END IF;
END;
/How can I improve the code?
Solution
I would suggest adding a temp column rather than renaming the existing one. In Oracle 10g I created a test table:
I then inserted data so that the results of length calls are as follows:
Result:
I then altered the table as follows:
As expected receive the following error:
ORA-22859: invalid modification of columns
Change the column using the following script:
Reissue the length sql:
CREATE TABLE "TEST"
( "A" CLOB
)I then inserted data so that the results of length calls are as follows:
select length(a) from testResult:
"LENGTH(A)"
12308
12308
12308
12308
12308I then altered the table as follows:
alter table "TEST" modify
("A" VARCHAR2(4000) NOT NULL)
/As expected receive the following error:
ORA-22859: invalid modification of columns
Change the column using the following script:
ALTER TABLE TEST ADD temp VARCHAR2(4000);
UPDATE TEST
SET temp = DBMS_LOB.SUBSTR (a, 4000),
a = NULL;
ALTER TABLE TEST DROP COLUMN A;
ALTER TABLE TEST RENAME COLUMN temp TO A;Reissue the length sql:
"LENGTH(A)"
4000
4000
4000
4000
4000Code Snippets
CREATE TABLE "TEST"
( "A" CLOB
)select length(a) from test"LENGTH(A)"
12308
12308
12308
12308
12308alter table "TEST" modify
("A" VARCHAR2(4000) NOT NULL)
/ALTER TABLE TEST ADD temp VARCHAR2(4000);
UPDATE TEST
SET temp = DBMS_LOB.SUBSTR (a, 4000),
a = NULL;
ALTER TABLE TEST DROP COLUMN A;
ALTER TABLE TEST RENAME COLUMN temp TO A;Context
StackExchange Database Administrators Q#5948, answer score: 4
Revisions (0)
No revisions yet.