Oracle SQL. How to change table field datatype CLOB-->VARCHAR2 - sql

I have database and some text fields are CLOB type, I need to change most of these into VARCHAR2.
Have tried to do that using SQL Developer tool, by clicking edit on table, but get error like this one:
The following SQL statement failed:
ALTER TABLE TBL_PEOPLE MODIFY (PERSON VARCHAR2(150) )
Want to ask, how can this change be done

You can't, directly. The code you tried will have got an `ORA-22859, presumably. (It's helpful to show the actual errors you get, of course).
You'll need to add a new varchar2 column; copy the data across - or a substring of it if it might be larger than the new column you're creating; drop the clob column. You can rename the columns so it looks fairly transparent.
As in this SQL Fiddle:
alter table tbl_people rename column person to clob_person;
alter table tbl_people add (person varchar2(150));
update tbl_people set person = clob_person;
alter table tbl_people drop column clob_person;
Obviously don't drop the old column until you're sure the data has copied without errors. Also take into account any constraints, indexes, etc. that might exist in the old column; they will need to be recreated. And anything that references the old column will have been invalidated - generally procedures will recompile themselves on next use.
So be careful, test it first, and plan some down time.

ALTER TABLE tablename ADD (FIELD_LIST_TEMP VARCHAR2);
UPDATE tablename SET FIELD_LIST_TEMP = FIELD_LIST;
ALTER TABLE tablename DROP COLUMN FIELD_LIST;
ALTER TABLE tablename RENAME COLUMN FIELD_LIST_TEMP TO FIELD_LIST;
Here FIELD_LIST existing column which is defined it as CLOB. With above query it will change from CLOB to VARCHAR2.

Related

I want to add two columns names to an existing table in Impala Query

I am writing the following query to add a column at a specified position but getting the below error:
alter table quantum_raw_dev.rpt_backup_allocation
change upt_type upt_type STRING after tray_size;
You can add one or more columns to the end of the column list using:
ALTER TABLE <table_name> ADD COLUMNS (col_name col_type, ...);
[note: there is NO comma between column name and type]
Adding or Removing Columns
You can add one or more columns to the end of the column list using ADD COLUMNS,
or (with Impala only) you can delete columns using DROP COLUMN.
The general syntax is
ALTER TABLE tablename ADD COLUMNS (col1 TYPE1,col2 TYPE2,… );
ALTER TABLE tablename DROP COLUMN colname;
For example, you can add a bonus integer column to the employees table:
ALTER TABLE employees ADD COLUMNS (bonus INT);
Or you can drop the office_id column from the employees table:
ALTER TABLE employees DROP COLUMN office_id;
Notes
DROP COLUMN is not available in Hive, only in Impala. However, see “Replacing All Columns” below.
You can only drop one column at a time.
To drop multiple columns, use multiple statements or use the method to replace columns (see below).
You cannot add a column in the middle of the list rather than at the end.
You can, however, add the column then change the order (see above) or use the method to replace columns (see below).
As with changing the column order, these do not change the data files.
If the table definition agrees with the data files before you drop any column other than the last one,
you will need to recreate the data files without the dropped column's values.
If you drop the last column, the data will still exist but it will be ignored when a query is issued.
If you add columns for which no data exists, those columns will be NULL in each row.
Replacing All Columns
You can also completely replace all the columns with a new column list.
This is helpful for dropping multiple columns,
<h1>or if you need to add columns in the middle of the list<h1>
<h2>(like your use case)<h2>
The general syntax is
ALTER TABLE tablename REPLACE COLUMNS (col1 TYPE1,col2 TYPE2,… );
This completely removes the existing list of columns and replaces it with the new list.
Only the columns you specify in the ALTER TABLE statement will exist, and they will be in the order you provide.
Note
Again, this does not change the data files, only the metadata for the table,
so you'll either want the new list to match the data files or need to recreate the data files to match the new list.
I do not think you can add columns in between columns in Impala like above.
You can backup the data, drop the and recreate with new structure, and load the table from backup. Also if you have HIVE in your system you can try to do below steps -
Add column first and then use below commands to move columns around.
ALTER TABLE tab ADD COLUMNS (id BIGINT);
This moves id column to the beginning.
ALTER TABLE tab CHANGE COLUMN id id BIGINT first;
This moves existing_col after id.
ALTER TABLE tab CHANGE COLUMN existing_col existing_col string AFTER id;
Please refresh/invalidate metadata after applying all DDLs.
You cannot add column in between. Best way is to archive the data in another table. Drop the impala old table and create a fresh table with new columns as per the desired location and then reinsert the data.

How To Alter Date column to Varchar2(20)? [duplicate]

How can I change DATA TYPE of a column from number to varchar2 without deleting the table data?
You can't.
You can, however, create a new column with the new data type, migrate the data, drop the old column, and rename the new column. Something like
ALTER TABLE table_name
ADD( new_column_name varchar2(10) );
UPDATE table_name
SET new_column_name = to_char(old_column_name, <<some format>>);
ALTER TABLE table_name
DROP COLUMN old_column_name;
ALTER TABLE table_name
RENAME COLUMN new_column_name TO old_coulumn_name;
If you have code that depends on the position of the column in the table (which you really shouldn't have), you could rename the table and create a view on the table with the original name of the table that exposes the columns in the order your code expects until you can fix that buggy code.
You have to first deal with the existing rows before you modify the column DATA TYPE.
You could do the following steps:
Add the new column with a new name.
Update the new column from old column.
Drop the old column.
Rename the new column with the old column name.
For example,
alter table t add (col_new varchar2(50));
update t set col_new = to_char(col_old);
alter table t drop column col_old cascade constraints;
alter table t rename column col_new to col_old;
Make sure you re-create any required indexes which you had.
You could also try the CTAS approach, i.e. create table as select. But, the above is safe and preferrable.
The most efficient way is probably to do a CREATE TABLE ... AS SELECT
(CTAS)
alter table table_name modify (column_name VARCHAR2(255));
Since we can't change data type of a column with values, the approach that I was followed as below,
Say the column name you want to change type is 'A' and this can be achieved with SQL developer.
First sort table data by other column (ex: datetime).
Next copy the values of column 'A' and paste to excel file.
Delete values of the column 'A' an commit.
Change the data type and commit.
Again sort table data by previously used column (ex: datetime).
Then paste copied data from excel and commit.

Rename table via sp_rename or ALTER SCHEMA

I am going to perform a table-wide update on a huge table (+200Millon records) so I am going to populate the data via SELECT into a separate table, than drop the original and rename the new one.
In one of the articles someone mentioned that it is better to create the new table with the same name in a temporary schema (e.g. 'clone') and switch it to the used one (e.g. 'dbo'), than to use the original schema with a temporary name and call sp_rename after the data is in place and the old table is dropped.
I was looking into this, but I cannot think of anything why the schema switch is better than the sp_rename. Can anyone find any good reason why is better to use the first or the second approach?
Thanks!
EDIT: I want to update the values in a specific column
EDIT2: Ultimately my question is, if I decide to go down the way of creating a new table to transfer data to which alternative to use:
CREATE TABLE dbo.newTable
...
DROP TABLE dbo.originalTable
EXEC sp_rename N'dbo.newTable', N'dbo.originalTable'
OR
CREATE TABLE clone.originalTable
...
DROP TABLE dbo.originalTable
ALTER SCHEMA dbo TRANSFER clone.originalTable
By the way, I would suggest that you WON'T populate the table by using SELECT * INTO. This will lock your source table for everyone else during the insertion, which could take quite a time.
Just a suggestion, try this instead:
SELECT TOP 0 INTO [newTable]
FROM [oldTable]
INSERT INTO [newTable]
SELECT * FROM [oldTable]
By the way, you can use sp_rename to rename your table to another name. But it won't change the schema. If you try to change the schema too it will produce a buggy table name.
You can instead try to move the table to another name. Example below:
EXEC sp_rename N'oldTable', N'oldTable_Backup'
EXEC sp_rename N'newTable', N'oldTable'
Hopefully this will help you.
Based on your edited answer the quickest way to do that is:
If you have to include default value to the column
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
[WITH VALUES]
and then drop the old column from the table.
ALTER TABLE {TABLENAME} DROP COLUMN {OLD COLUMN}
If you have to update table column based calculated values
Disable index on the column which you are updating
Create index on the column which are in WHERE clause
Update statistics
Use WITH(NOLOCK) table hint [if you are fine with dirty read]
Update
As per edit 2, your first statement is about changing table name and second statement is about changing schema. They both are different and does not related to moving data or updating value. In this case, changing schema would be the best bet
If locking was an issue before it still is regardless of what version SQL Server that you are using. When you drop and rename you are also losing all the rights on the table.

Alter the data type of a column in MonetDB

How can I alter the type of a column in an existing table in MonetDB? According to the documentation the code should be something like
ALTER TABLE <tablename> ALTER COLUMN <columnname> SET ...
but then I am basically lost because I do not know which standard the SQL used by MonetDB follows here and I get a syntax error. If this statement is not possible I would be grateful for a workaround that is not too slow for large (order of 10^9 records) tables.
Note: I ran into this problem while doing some bulk data imports from csv files into a table in my database. One of the columns is of type INT but the values in the file at some point exceed the INT limit of 2^31-1 (yes, the table is big) and so the transaction aborts. After I found out the reason for this failure, I wanted to change it to BIGINT but all versions of SQL code I tried failed.
This is currently not supported. However, there is a workaround:
Example table for this example, say we want to change the type of column b from integer to double.
create table a(b integer);
insert into a values(42);
Create a temporary column alter table a add column b2 double;
Set data in temporary column to original data update a set b2=b;
Remove the original column alter table a drop column b;
Re-create the original column with the new type alter table a add column b double;
Move data from temporary column to new column update a set b=b2;
Drop the temporary column alter table a drop column b2;
Profit
Note that this will change the ordering of columns if there are more than one. However, this is only a cosmetic issue.

Change column type without losing data

I am working on an SQL Database, I have a column named "Price". When the database was created the column "Price" was set to NVARCHAR I need to change its type to decimal(18, 2) without losing the data in the database. This should be done by an SQL Script
I thought of creating a new column, moving the data to it, remove the old column, and then rename the newly created column.
Can someone help me with an example on how to do this?
Also is there a function in SQL to Parse string to decimal?
Thanks
You don't need to add a new column two times, just remove the old one after updating the new one:
ALTER TABLE table_name ADD new_column_name decimal(18,2)
update table_name
set new_column_name = convert(decimal(18,2), old_column_name)
ALTER TABLE table_name DROP COLUMN old_column_name
Note that if the old_column_name is not numeric, the convert may fail.
Something Like
Alter Table [MyTable] Add Column NewPrice decimal(18,2) null
Then
Update [MyTable] Set NewPrice = Convert(decimal(18,2),[Price]) Where Price is not null
If the above fails then you'll need to beef it up to deal with the funnies
Once you are happy drop the old column with an Alter Table and rename the new one with sp_rename
If you just want to change only column's data type, you can do like this=>
Alter Table YourTableName
Alter Column ColumnName DataType
I already test this on SQL server 2012 and its work.
You can make those changes visually using Management Studio. Then, use the button "Generate Change Script" to get the script for the changes you made. Be sure to do all testing in a copy of the original ddbb, in case something goes wrong..