Error while dropping a column - sql

I just created a table as below in MS SQL
create table Employee
(emp_id smallint not null,
employee_name varchar (30) not null,
salary money not null,
department varchar(30),
address varchar(40),
primary key(emp_id)
)
After creating the table, I feel like auto populating the emp_id column( using Identity). So, I was trying to drop the column emp_id as below:
alter table Employee
drop column emp_id
Even though, I haven't inserted any rows in the table yet, I am getting the error
Msg 5074, Level 16, State 1, Line 1 The object
'PK__Employee__1299A86183CA4FBC' is dependent on column 'emp_id'. Msg
4922, Level 16, State 9, Line 1 ALTER TABLE DROP COLUMN emp_id failed
because one or more objects access this column.
Please help!!!

Something like this can help .
ALTER TABLE Employee
DROP CONSTRAINT PK__Employee__1299A86183CA4FBC;
alter table Employee
drop column emp_id

I solved the problem by executing below query: I need to remove a column and all the entries from that column to free my DB size my initial table structure is as shown below:
CREATE TABLE words(_id,word,synonyms,favorite,history,updDate)
And I wanted the table in below form
CREATE TABLE words(_id,word,favorite,history,updDate)
So I executed below query and it removed "synonyms" column
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(_id,word,favorite,history,updDate);
INSERT INTO t1_backup SELECT _id,word,favorite,history,updDate FROM words;
DROP TABLE words;
CREATE TABLE words(_id,word,favorite,history,updDate);
INSERT INTO words SELECT _id,word,favorite,history,updDate FROM t1_backup;
DROP TABLE t1_backup
COMMIT;

Related

How do I select insert into select a table which already has values in the primary key column without adding new rows?

I'm working on a database for my school project in which I have to produce a functional database by normalizing sample tables given to us.
One table I'm having trouble with is itineraries. I produce 3 tables from the normalization which are "Destinations", "Itineraries" and "Itinerary_Destinations".
The code for Destinations is:
create table Destinations
(
DestinationID varchar(5) primary key,
Name varchar(45)
);
The code for Itineraries is:
create table Itineraries
(
ItineraryID varchar(5),
Name varchar(45)
);
The code for the last table is:
create table Itinerary_Destinations
(
DI varchar(5) primary key,
ItineraryID varchar(5) foreign key references Itineraries(ItineraryID),
Itinerary_Name varchar(45),
DestinationID varchar(5) foreign key references Destinations(DestinationID),
Destination_Name varchar(45)
);
Data has already been inserted into all 3 tables with the exception of 'Destination_Name' and 'Itinerary_Name' columns. The code I'm attempting to use is returning as error. The code is shown below.
insert into Itinerary_Destinations (Itinerary_name)
select Name from Itineraries where
Itineraries.ItineraryID = ItineraryID;
The error it returns is
Msg 515, Level 16, State 2, Line 1 Cannot insert the value NULL into
column 'DI', table 'DDDAssignment.dbo.Itinerary_Destinations'; column
does not allow nulls. INSERT fails. The statement has been terminated.
Is there a method to accomplish the task of inserting the Destination_Name and Itinerary_Name without creating new records that require primary keys?
Or should I do it manually?
If you want to modify records which already exist, then you should be using an UPDATE rather than an INSERT:
UPDATE a
SET Itinerary_name = b.Name
FROM Itinerary_Destinations a
INNER JOIN Itinerary_name b
ON a.ItineraryID = b.ItineraryID;
But, if you do have some data which is not already logically associated with the Itinerary_Destinations table, then using an insert is appropriate.
use coalesce funtion in case null it will insert blank string, as your column does not allow null value thats why you got that error in your query
insert into Itinerary_Destinations (Itinerary_name)
select coalesce(Name,' ') from Itineraries where
Itineraries.ItineraryID = ItineraryID;

Add a new column in table with a sequence - Oracle

I have a table that has 60 million rows of data. I would like to introduce a new column say "id" for the table that is an auto incremented sequence.
For example:
CREATE TABLE Persons (
LastName varchar(255),
FirstName varchar(255)
);
INSERT INTO Persons VALUES ('abc', 'def');
INSERT INTO Persons VALUES ('abcd', 'ghi');
CREATE SEQUENCE "PERSON_SEQUENCE" START WITH 1 INCREMENT BY 1;
ALTER TABLE PERSONS ADD (PERSONID NUMBER);
UPDATE persons SET personid = PERSON_SEQUENCE.NEXTVAL;
In the above sql statements, I am able to create a sequence then alter the table and update it.
Since the amount of data I need to update is large.. I would like to perform this with as much low cost as possible.
I am trying to do so something like this:
ALTER TABLE PERSONS ADD (PERSONID NUMBER DEFAULT(PERSON_SEQUENCE.NEXTVAL));
but the above does not work. Oracle throws me the below error:
Error starting at line :
1 in command - ALTER TABLE PERSONS ADD (PERSONID NUMBER
DEFAULT(PERSON_SEQUENCE.NEXTVAL)) Error report -
ORA-00984: column not allowed here
00984. 00000 - "column not allowed here"
*Cause:
*Action:
However this works:
ALTER TABLE PERSONS ADD (PERSONID NUMBER DEFAULT(0));
Could some one help me with how I can achieve to alter a table (create a new column) and populate the column with a seq id both in a single sql. Thank you!
For a table with 60 million rows, I would not do an add column + insert, but create the table new:
RENAME persons TO persons_old;
CREATE TABLE Persons (
personid number,
LastName varchar(255),
FirstName varchar(255)
);
INSERT INTO persons (personid, lastname, firstname)
SELECT person_sequence.nextval, lastname, firstname
FROM persons_old;
DROP TABLE persons_old;
If this is still taking too long, speak to your DBA about ALTER TABLE NOLOGGING and INSERT /*+ APPEND */ and PARALLEL DML.
EDIT: Ah, yes, for 60 million you could even increase the cache size of the sequence for the initial assignment:
ALTER SEQUENCE PERSON_SEQUENCE CACHE 1000;
This worked for me:
alter table PERSONS add (PERSON_ID number default PERSON_SEQ.nextval);

Update trigger assistance

Evening, needing assistance regarding triggers.
Within my development environment I have two tables, one containing employee data (which contains various data errors that will be amended via ALTER TABLE) and the log table.
How do i go about designing a trigger that will update multiple rows contained within the log table such as 'issue_status','status_update_date' when ALTER TABLE sql is used to amend the data contained in the first data table?
-- employee table
CREATE TABLE emp(
emp_id INTEGER NOT NULL,
emp_name VARCHAR(30),
emp_postcode VARCHAR(20),
emp_registered DATE,
CONSTRAINT pk_emp PRIMARY KEY (emp_id));
-- SQL for the log table
CREATE TABLE data_log
(issue_id NUMBER(2) NOT NULL,
table_name VARCHAR2(20),
row_name VARCHAR2(20),
data_error_code NUMBER(2),
issue_desc VARCHAR2(50),
issue_date DATE,
issue_status VARCHAR2(20),
status_update_date DATE);
-- example log insert
INSERT INTO data_log( SELECT DI_SEQ.nextval, 'emp', emp.emp_id, '1', 'emp_name case size not UPPER', SYSDATE, 'un-fixed', '' FROM emp WHERE emp_name != UPPER(emp_name));
This is the example of the issue inserted into the log table. All i want to do is if I update the emp table to set 'emp_name' to Upper the trigger will register this update and change the rows 'issue_status' and 'status_update_date' to 'fixed' and the 'sysdate' of when the change was made
I've done some browsing however i'm still struggling to understand, any literature recommendations would be appreciated also.
Thanks in advance for the assistance.
Note that we don't use ALTER TABLE to update the rows of a table as you have mentioned.We use Update statement. Your trigger should be a BEFORE UPDATE TRIGGER like this.
CREATE OR REPLACE TRIGGER trig_emp_upd BEFORE
UPDATE ON emp
FOR EACH ROW
WHEN ( new.emp_name = upper(old.emp_name) )
BEGIN
UPDATE data_log
SET
issue_status = 'fixed',
status_update_date = SYSDATE
WHERE
row_name =:new.emp_id;
END;
/

Restoring a Truncated Table from a Backup

I am restoring the data of a truncated table in an Oracle Database from an exported csv file. However, I find that the primary key auto-increments and does not insert the actual values of the primary key constrained column from the backed up file.
I intend to do the following:
1. drop the primary key
2. import the table data
3. add primary key constraints on the required column
Is this a good approach? If not, what is recommended? Thanks.
EDIT: After more investigation, I observed there's a trigger to generate nextval on a sequence to be inserted into the primary key column. This is the source of the predicament. Hence, following the procedure above would not solve the problem. It lies in the trigger (and/or sequence) on the table. This is solved!
easier to use your .csv as an external table and then go
create table your_table_temp as select * from external table
examine the data in the new temp table to ensure you know what range of primary keys is present
do a merge into the new table
samples from here and here
CREATE TABLE countries_ext (
country_code VARCHAR2(5),
country_name VARCHAR2(50),
country_language VARCHAR2(50)
)
ORGANIZATION EXTERNAL (
TYPE ORACLE_LOADER
DEFAULT DIRECTORY ext_tab_data
ACCESS PARAMETERS (
RECORDS DELIMITED BY NEWLINE
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
(
country_code CHAR(5),
country_name CHAR(50),
country_language CHAR(50)
)
)
LOCATION ('Countries1.txt','Countries2.txt')
)
PARALLEL 5
REJECT LIMIT UNLIMITED;
and the merge
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
Edit: after you have merged the data you can drop the temp table and the result is your previous table with the old data and the new data together
Edit you mention " During imports, the primary key column does not insert from the file, but auto-increments". This can only happen when there is a trigger on the table, likely, Before insert on each row. Disable the trigger and then do your import. Re-enable the trigger after committing your inserts.
I used the following procedure to solve it:
drop trigger trigger_name
Imported the table data into target table
drop sequence sequence_name
CREATE SEQUENCE SEQ_NAME INCREMENT BY 1 START WITH start_index_for_next_val MAXVALUE max_val MINVALUE 1 NOCYCLECACHE 20 NOORDER
CREATE OR REPLACE TRIGGER "schema_name"."trigger_name"
before insert on target_table
for each row
begin
select seq_name.nextval
into :new.unique_column_name
from dual;
end;

create unique numerical identifier column in oracle sql

I have a table that has a list of states. I did this to create the table:
CREATE TABLE drb (
Statename VARCHAR2(15)
)
I then inserted the state data. However, I want my first column to be a created unique state ID. So it should list 1-50 for the 50 states in the United States. I tried searching different unique tutorials like this and nothing seemed to work.
Essentially, I want to know how to get a unique numerical key for a variable
Your table should have id field along with statename, add it this way.
CREATE TABLE drb (
id NUMBER,
Statename VARCHAR2(15)
);
Make id as primary key:
alter table drb
add constraint drb_pk primary key (id);
Create a sequence as follows:
create ore replace sequence drb_sequence
start with 1 increment by 1;
Create a trigger which will insert a unique id into drb table as follows:
create or replace trigger drb_trigger
before insert on drb
for each row
begin
select drb_sequence.nextval into :new.id from dual;
end;
/
Now insert into drb:
insert into drb(Statename) values('state one');
Select from drb:
select * from drb;
Output :
--------------------------
|id Statename |
--------------------------
|1 state one |
--------------------------
Hope it helps.