I am looking to repair a table of data in Oracle, ideally via unprivileged SQL, which has had UTF-8 data inserted into a UTF-8 database, using the Latin-1 character set by mistake.
The symbol β GREEK SMALL LETTER BETA
should have gone into the database, but instead the two characters β
have gone in...as the two UTF-8 characters
Î LATIN CAPITAL LETTER I WITH CIRCUMFLEX
followed by ² SUPERSCRIPT TWO
.
This example code demonstrates the problem and the fix, however it only works with VARCHAR
columns. As soon as a CLOB
is used, the conversion fails:
-- This must return AL32UTF8 for this example to be valid
SELECT VALUE FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER='NLS_CHARACTERSET';
CREATE TABLE EXAMPLE (T VARCHAR2(20));
INSERT INTO EXAMPLE (T) VALUES ('Example β');
SELECT T FROM EXAMPLE; -- Should return 'Example β'
SELECT CONVERT(T, 'WE8ISO8859P1') FROM EXAMPLE;
UPDATE EXAMPLE SET T=CONVERT(T, 'WE8ISO8859P1');
SELECT T FROM EXAMPLE; -- Should return 'Example β', problem fixed
DROP TABLE EXAMPLE;
However if the VARCHAR2(20)
is changed to CLOB
then this no longer works. CONVERT()
returns garbage characters. I can use TO_CHAR()
to work around the problem, but eventually I get an error that the CLOB
is longer than 4000 chars so TO_CHAR()
fails.
Is there a way to get the above example working, when using a CLOB
column that's longer than 4000 chars?
¿
.US7ASCII
character set. This should only allow character codes 0-127 but Oracle will happily let you use the full 255 available characters. Depending on the client you either extract your original data unchanged, or you get� REPLACEMENT CHARACTER
. Converting the whole DB toAL32UTF8
with this kind of incorrect data is the source of my problem.