Oracle varchar2 to nvarchar2 conversion - oracle

If I change an existing column type from varchar2 to nvarchar2 in Oracle will Oracle automatically convert existing column data between character set or should I do it myself?
I'm using Oracle 11g, the varchar2 character set is WE8MSWIN1252 and the nvarchar2 character set is AL16UTF16

You can use the package DBMS_REDEFINITION for doing the changing the varchar2 to nvarchar2 column for a table
Please find the below link which might be helpful
Using Online Table Redefinition to Migrate a Large Table to Unicode
Also find the documentation for General Character set Migration
General Character set Migration

Related

Find total number of characters in CLOB and XMLTYPE datatype column

I have Oracle 12c version database.
I created table with CLOB and XMLTYPE datatype columns and Inserted some sample data.
I need to find total number of character in CLOB and XMLTYPE column.
Whatever the character-set used in those columns, just need a count.
Those two columns have huge data. So string operation ( i.e length() ) is not possible.
How to find the total number of character in those two columns.
Thanks in advance.
you can use the getlength in dbms_lob package
select
dbms_lob.getlength(t.clob_col)
,dbms_lob.getlength(t.XML_col.getClobVal())
from table t
db<>fiddle here

Automatic adjustment of a field in Oracle

Hello I'm trying to create a table under Oracle 18.1 (SQL Dev).
But I have an error "ORA-00906: missing right parenthesis"
CREATE TABLE DIM_TAB (
ID Number PRIMARY KEY,
TEST nvarchar2,
TEST_2 nvarchar,
DATE DATE not null
);
How to create a field without specifying the size of it in nvarchar (or nvarchar2) on Oracle? (I want the field size to adjust automatically)
Thank you
You have three problems. One, you must specify a maximum number of characters for a VARCHAR2 or NVARCHAR2 column. If you have data that will exceed 4000 bytes (not characters), then just use a CLOB. Second, there is no NVARCHAR data type. Third, you cannot create a column named "date," since that's a reserved word. What you want is something like this:
CREATE TABLE DIM_TAB (
id number PRIMARY KEY,
test nvarchar2(30),
test_2 nvarchar2(30),
the_date date not null
);
Personally, I would use a NUMBER(10) for your id, but that's a minor quibble.
You might want to read up on the NCHAR and NVARCHAR data types.

Oracle change column type from CLOB to NCLOB

We are using Oracle and we have a requirement to allow greek characters to be stored in the DB. Currently, our DB instance doesn't let us insert greek characters such as 'ϕ'. On googling, I found that it is to do with the character set. My oracle uses NLS_CHARACTERSET - WE8MSWIN1252 that doesn't support greek characters. I will have to change the character set to one of AL32UTF8, UTF8, AL16UTF16 or WE8ISO8859P7 if it has to work. Now that we have so much of data in the DB already, it would be a risk to change the character set now.
The other option I have is to change the column type (used to insert greek) from CLOB or VARCHAR2 to NVARCHAR2 and it works fine.
Before changing the column type, I want to know what are the risks involved in changing column type from CLOB to NVARCHAR2 and what are the things I need to keep in mind before changing.
Also, I would like to know the pros and cons of changing my existing character set to AL32UTF8.
EDIT:
There is also an option of changing CLOB to NCLOB and this seems to be less risky as both are closely related (almost same) types. Please do let me know the pros and cons of changing CLOB to NCLOB.
Ok. I was googling and posting Qs in other forums and got a much needed answer in here.
https://www.toolbox.com/tech/oracle/question/migrating-clob-to-nclob-010917/
So I just encountered this myself and I had issues with the above solution as it didn't copy across the foreign keys and constraints of my other columns. To get round this I did the following
created a new column for my NCLOB data,
ALTER TABLE table_name
ADD new_table_column NCLOB;
I then copied my CLOB data into my new NCLOB data column using the TO_NCLOB() function
UPDATE table_name
SET new_table_column = TO_NCLOB(old_table_column);
3)Finally I dropped the old column and then renamed my new column to my old column name
ALTER TABLE table_name
DROP COLUMN old_table_column;
ALTER TABLE table_name
RENAME COLUMN new_table_column TO old_table_column;
Please make sure you backup your data if you do this though as dropping the column will get rid of it and commit any transactions you've got
I also did this in Oracle so the syntax may differ slightly in other versions of SQL.

Conversion between NVARCHAR to VARCHAR

I've got an Oracle DB with ALL the character columns defined as NVARCHAR or NCHAR or NCLOB, using charset UTF-16.
Now I want to migrate to a new DB that has charset UTF-8. Since it can store unicode characters, I'm wandering if I will be able to import data converting column types.
The reason I'm doubtful is I know that I cannot convert a NVARCHAR2 column in a VARCHAR2 if not empty.
What is the best option to perform the import. Will datapump complain if I import the schema, modify the column types and after that I'll import the data?
Thank
Yes datapump would be unimpressed with your proposed solution. You need to use to_char() or cast( MYNVARCHAR2 as VARCHAR2 ) to convert the datatypes after the import or before the export. As far as I know, any characters which can't be converted will be turned into '?'s so you have to be careful not to convert any data that contains non-english-alphabet characters.
It will probably be easiest to just import the data as is into a different schema, then convert the data while copying it to the correct, modified schema. i.e.
impdp remap_schema=myschema:tempschema
insert into myschema.mytable (select myprimarykey, to_char(mynvarchar2) from tempschema.mytable);
But this will obviously use up twice the space in your database.

Why does Char(1) change to Char(3) when copying over an Oracle DBLINK?

I have 2 databases, and I want to transport an existing table containing a CHAR column from database A to database B.
Database A is Oracle 9i, has encoding WE8ISO8859P1, and contains a table "foo" with at least 1 column of type CHAR(1 char). I can not change the table on database A because it is part of a third party setup.
Database B is my own Oracle 10g database, using encoding AL32UTF8 for all kinds of reasons, and I want to copy foo into this database.
I setup a database link from database B to database A. Then I issue the following command:
*create table bar as select * from #link#.foo;*
The data gets copied over nicely, but when I check the types of the columns, I notice that CHAR(1 char) has been converted into CHAR(3 char), and when querying the data in database B, it is all padded with spaces.
I think somewhere underwater, Oracle confuses it's own bytes and chars. CHAR(1 byte) is different from CHAR(1 char) etc. I've read about all that.
Why does the datatype change into a padded CHAR(3 char) and how do I stop Oracle from doing this?
Edit: It seems to have to do with transfering CHAR's between two specific patchlevels of Oracle 9 and 10. It looks like it is really a bug. as soon as I find out I'll post an update. Meanwhile: don't try to move CHAR's between databases like I described. VARCHAR2 works fine (tested).
Edit 2: I found the answer and posted it here: Why does Char(1) change to Char(3) when copying over an Oracle DBLINK?
Too bad I can not accept my own answer, because my problem is solved.
This problem is caused by the way Oracle (mis)handles character conversions between different character sets based on the original column length definition. When you define the size of a character type column in bytes, Oracle does not know how to do a conversion and bodges it. The solution is to always define the length of a character type in characters.
For a more in-depth explanation of the problem and how I figured this out have a look at
http://www.rolfje.com/2008/11/04/transporting-oracle-chars-over-a-dblink/
YOu need to learn the difference between the WE8ISO8859P1 NLS (which stores characters in one byte) and the AL32UTF8 which stores characters in up to four bytes. You will need to spend some quality time with the Oracle National Language Support (NLS) Documentation. Oracle automatically does the conversion through the database link, in an attempt to be helpful.
Try the following from your SQL prompt:
ALTER SESSION NLS_NCHAR WE8ISO8859P1
create table bar as select * from #link#.foo;
The first thing I would try is Creating the table NOT as a CTAS but with a list of column definitions and try to perform an insert of the first few thousand rows. If that didn't succeed then it would be very clear why... and you'd have quick confirmation that Thomas Low is dead on accurate.

Resources