How to alter the data type of a column from varchar2 to number in Oracle database - oracle

When I ran the alter query, I get error saying that column to be modified must me empty.
Table : Monthly_Result (Id Number(38,0), dealer_ID varchar2, sales_revenue Number(38,2))
dealer_Id should be changed to Number(38,0)
Please help

As Alex mentioned in his comment you will need to add new column; update it and check values were converted correctly; then drop the old column when you're ready.
-- step 1
alter table monthly_result add tmp number(38, 0);
update monthly_result set tmp = to_number(dealer_id);
-- step 2
-- check values are set correctly in tmp
-- step 3
alter table monthly_result rename column dealer_id to dealer_id_old;
alter table monthly_result rename column tmp to dealer_id;
-- step 4
alter table monthly_result drop column dealer_id_old;

Please try this it would be help the update add column things you will loss your primary key and position of the table:
--COPY THE DATA TO TEMPORARY TABLE
CREATE TABLE _TMP AS SELECT * FROM ;
--TRUNCATE OLD DATA
TRUNCATE TABLE ;
--ALTER SPECIFIC COLUMN TYPE
alter table MODIFY number(38, 0);
--BRING THE DATA FROM WHICH COPY PREVIOUS TEMPORARY TABLE
INSERT INTO SELECT * FROM _TMP;
--CHECK YOUR DATA
SELECT * FROM ;
--DROP YOUR TEMPORARY TABLE
DROP TABLE _TMP;
I believe it will work for you.

Related

How to use NEWSEQUENTIALID() after a table has already been created and has data?

Could anyone help me with this please. I have a table that's not unique (as I'm rummaging through old databases of my predecessor.)
I would like to assign it to the "ID" field within the Fruits table I have.
I'd like to go ahead and get the NEWSEQUENTIALID() to be setup so I can see all what I'm working with.
Assuming ID is of type uniqueidentifier, you can create another column with sequential guids as default.This will populate the values in that column. After that you may copy these values to your id column and then drop the tmp column. Once all data is in, then specify defaults for your id column. See SQL Script below :
--create a new column with default as sequential ids
USE [BASKET]
ALTER TABLE [FRUITS]
ADD [TMPID] UNIQUEIDENTIFIER NOT NULL CONSTRAINT DF_TMPID DEFAULT NEWSEQUENTIALID()
GO
--update existing id column values with the newly created values
UPDATE [FRUITS] SET ID = TMPID GO
--remove constraint
ALTER TABLE [FRUITS] DROP CONSTRAINT DF_TMPID GO
--remove the temp column
ALTER TABLE [FRUITS] DROP COLUMN TMPID GO
--specify defaults for newly inserted defaults
ALTER TABLE [FRUITS] ADD DEFAULT NEWSEQUENTIALID() FOR ID
--or--
ALTER TABLE [FRUITS] ADD CONSTRAINT DF_ROWGUID DEFAULT NEWSEQUENTIALID() FOR ID;
CREATE PROCEDURE [dbo].[uspGetSequentialGuid]
AS
DECLARE #SequentialGuids as Table ( SequentialGuid uniqueidentifier DEFAULT NEWSEQUENTIALID() PRIMARY KEY,InitDate datetime )
BEGIN
INSERT INTO #SequentialGuids(InitDate) Values(GETDATE());
END
SELECT SequentialGuid from #SequentialGuids
GO
CREATE PROCEDURE [dbo].[uspGetSequentialGuids](#RequiredGuids as int)
AS
DECLARE #SequentialGuids as Table ( SequentialGuid uniqueidentifier DEFAULT NEWSEQUENTIALID() PRIMARY KEY,InitDate datetime )
Declare #Counter int
SET #Counter = 0
While #Counter < #RequiredGuids
BEGIN
INSERT INTO #SequentialGuids(InitDate) Values(GETDATE());
SET #Counter = #Counter + 1
END
SELECT SequentialGuid from #SequentialGuids
GO

Truncate data and if insert new row column increment from 1

I have table with two rows which one ID with auto increment and there are much row last number ID is 89. And then I truncate data/row in the table. And then I insert row again.
But number ID from 90 not from 1 (one). If in mysql if I truncate data in table auto increment start from 1 (one) again. So how in oracle I want to ID autoincrement from one again. Thanx.
Below step when I create table:
// create table;
CREATE TABLE tes (
id NUMBER NULL,
ip_address varchar2(25) NOT NULL
PRIMARY KEY (id)
);
// and create increment;
CREATE SEQUENCE tes_sequence START WITH 1 INCREMENT BY 1;
// and create trigger;
CREATE OR REPLACE TRIGGER tes_trigger
BEFORE INSERT
ON tes
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT tes_sequence.nextval INTO :NEW.ID FROM dual;
END;
Oracle sequence is a separate object and is not connected with table. If you need to start sequence after truncating a table you need to alter the sequence. Have a look here: How do I reset a sequence in Oracle?

Trigger to enter deleted entries to a new table - SQL plus

I am trying to create a trigger which will enter values into a table terminated_employees when we delete values from the nm_employees table. I have written the trigger but it does not work. Is my trigger format right? Any ideas?
CREATE TABLE nm_departments(
dept2 varchar(20),
CONSTRAINT empPK PRIMARY KEY (dept2)
);
CREATE TABLE nm_employees(
name varchar(20),
dept varchar(20),
CONSTRAINT departments FOREIGN KEY (dept) REFERENCES nm_departments (dept2)ON DELETE CASCADE
);
CREATE TABLE terminated_employees(
te_name varchar(20),
te_dept varchar(20)
);
CREATE TRIGGER term_employee AFTER DELETE ON nm_employee
FOR EACH ROW
BEGIN
INSERT INTO terminated_employees (NEW.te_name, NEW.te_dept) VALUES (OLD.name,OLD.dept)
END;
You should not be specifying the NEW. on the column names of your INSERT statement. These are the columns in the terminated_employees table, NOT the new values. i.e.
INSERT INTO terminated_employees (te_name, te_dept)
VALUES (OLD.name,OLD.dept)
You can use show errors (or show err) in SQL*Plus to see the exact error.
You have a number of problems:
Wrong table name on create trigger (missing the s)
Missing ; after instert statement
The OLD. need to have : prefix. i.e. :OLD.name

Alter column data type in production database

I'm looking for the best way to change a data type of a column in a populated table. Oracle only allows changing of data type in colums with null values.
My solution, so far, is a PLSQL statement which stores the data of the column to be modified in a collection, alters the table and then iterates over the collection, restoring the original data with data type converted.
-- Before: my_table ( id NUMBER, my_value VARCHAR2(255))
-- After: my_table (id NUMBER, my_value NUMBER)
DECLARE
TYPE record_type IS RECORD ( id NUMBER, my_value VARCHAR2(255));
TYPE nested_type IS TABLE OF record_type;
foo nested_type;
BEGIN
SELECT id, my_value BULK COLLECT INTO foo FROM my_table;
UPDATE my_table SET my_value = NULL;
EXECUTE IMMEDIATE 'ALTER TABLE my_table MODIFY my_value NUMBER';
FOR i IN foo.FIRST .. foo.LAST
LOOP
UPDATE my_table
SET = TO_NUMBER(foo(i).my_value)
WHERE my_table.id = foo(i).id;
END LOOP;
END;
/
I'm looking for a more experienced way to do that.
The solution is wrong. The alter table statement does an implicit commit. So the solution has the following problems:
You cannot rollback after alter the alter table statement and if the database crashes after the alter table statement you will loose data
Between the select and the update users can make changes to the data
Instead you should have a look at oracle online redefinition.
Your solution looks a bit dangerous to me. Loading the values into a collection and subsequently deleting them fom the table means that these values are now only available in memory. If something goes wrong they are lost.
The proper procedure is:
Add a column of the correct type to the table.
Copy the values to the new column.
Drop the old column.
Rename the new column to the old columns name.

How to set default value for column of new created table from select statement in 11g

I create a table in Oracle 11g with the default value for one of the columns. Syntax is:
create table xyz(emp number,ename varchar2(100),salary number default 0);
This created successfully. For some reasons I need to create another table with same old table structure and data. So I created a new table with name abc as
create table abc as select * from xyz.
Here "abc" created successfully with same structure and data as old table xyz. But for the column "salary" in old table "xyz" default value was set to "0". But in the newly created table "abc" the default value is not set.
This is all in Oracle 11g. Please tell me the reason why the default value was not set and how we can set this using select statement.
You can specify the constraints and defaults in a CREATE TABLE AS SELECT, but the syntax is as follows
create table t1 (id number default 1 not null);
insert into t1 (id) values (2);
create table t2 (id default 1 not null)
as select * from t1;
That is, it won't inherit the constraints from the source table/select. Only the data type (length/precision/scale) is determined by the select.
The reason is that CTAS (Create table as select) does not copy any metadata from the source to the target table, namely
no primary key
no foreign keys
no grants
no indexes
...
To achieve what you want, I'd either
use dbms_metadata.get_ddl to get the complete table structure, replace the table name with the new name, execute this statement, and do an INSERT afterward to copy the data
or keep using CTAS, extract the not null constraints for the source table from user_constraints and add them to the target table afterwards
You will need to alter table abc modify (salary default 0);
new table inherits only "not null" constraint and no other constraint.
Thus you can alter the table after creating it with "create table as" command
or you can define all constraint that you need by following the
create table t1 (id number default 1 not null);
insert into t1 (id) values (2);
create table t2 as select * from t1;
This will create table t2 with not null constraint.
But for some other constraint except "not null" you should use the following syntax
create table t1 (id number default 1 unique);
insert into t1 (id) values (2);
create table t2 (id default 1 unique)
as select * from t1;

Resources