How to prevent duplicate rows in insert query using Oracle? - sql

I have table A in Oracle that has a primary key (id). I need to insert data into this table.
How do I prevent duplicate rows?

If the id column is marked as the PK you will not be able to insert a duplicate key, the server will throw an exception.
If you will insert duplicate data with different key - that's a logic that you need to deal with (like putting a unique constraint on the actual data) or do a check before you insert.

If you mean that you have rows that are identical (apart from the primary key) and you want to know how to delete them then do:
select col2, col3, ...coln, min(id) from A
group by col2, col3, ...coln
(I.e. select on all columns except the id.)
To get the unique instances do
delete from A where id not in
(select min(id) from A
group by col2, col3, ...coln) as x
to delete all rows except the unique instances (i.e. the duplicates).

First you would create a unique id on this table that has a sequence. Then when you insert into that table, in the insert statement you can use:
tableName_sn.nextval
in a statement like:
inserti into tableName (id) values (tableName_sn.nextval)
to get the next unique key in the sequence. Then if you use this key you will guarantee that it is unique. However, the caveat to that is if someone just entered a key not using the nextval function you will get primary key violations.

Related

ADD combination constraint into a dabase table

I want to make a combination of columns in a table unique which they can not have any duplicates value.
For example, I have a table of Person which contain a name, age, address and phone_number.
I want that the combination of (name, age, phone_number) must be unique.
The table person contain this data:
"Name1"|22|"adresse1"|000000
So the combination (''Name1'' and 22 and 000000) it has to be unique but if only one of them changed for example ("name2",22,000000) it will be permitted to insert data to the table.
How can I manage that with SQL please?
If you want a column or combination of columns to be unique, you can implement a unique constraint or index (they are functionally equivalent for this purpose):
create unique index unq_t_col1_col2_col3 on t(col1, col2, col3);
And for a constraint:
alter table t add constraint unq_t_col1_col2_col3
unique (col1, col2, col3);
Any attempt to insert values into the columns that already exists will result in an error, as will any attempt to update the columns with values in a different row.

Primary key conflict when merging databases (auto-increment)

I have two SQLite databases which I would like to merge. I'm doing it by using the following commands:
ATTACH "c:\other.db" AS SecondaryDB
INSERT INTO MyTable SELECT * FROM SecondaryDB.MyTable
The problem is that MyTable has a primary column id which is auto-incremented in both databases. Thus, there is a primary key conflict.
How can I insert the rows from the secondary database such that auto-increment is used for the id column starting from the last value of the first database?
You want to copy all rows from the source, but without the auto-incremented column.
Just enumerate the columns in the insert and select clauses - all, expected the primary key column. SQLite will automatically assign new values to the auto-incremented column.
Say that the columns of your table is id, col1, col2, col3, you would do:
ATTACH "c:\other.db" AS SecondaryDB
INSERT INTO MyTable(col1, col2, col3)
SELECT col1, col2, col3 FROM SecondaryDB.MyTable

Recently attended one interview. Unable to answer this one, can you help me out

Let's say there are two tables names like
Table-A has two columns col1,col2.
Table-B has two columns col3,col4.
col1 is primary key, col3 is foreign key dependent on col1. col4 is primary key, col2 is foreign key dependent on col4. So, both the tables are dependent on each other.
Now, I want to insert a record into table-A. How can I do this (in oracle 11g)?
You can defer the constraint evaluation until commit.
ALTER TABLE table_1
ADD CONSTRAINT fk_table_1 (col2 ) REFERENCES table_2( col4)
INITIALLY DEFERRED DEFERRABLE;
This will postpone the constraint checking to the committing time.
The short answer is, you can't. That is, you cannot insert a record into Table_A without also inserting a record into Table_B.
What the interviewer was probably hoping for:
Given that we need to insert records into both tables simultaneously can we do that?
Nope: the insert all syntax will fail on ORA-02291: integrity constraint WHATEVER_FK) violated - parent key not found
insert all
into table_a values (n1, n2)
into table_b values (n2, n1)
select 23 as n1
, 42 as n2
from dual
/
The workaround is to change the foreign keys so they are deferred:
alter table table_a add constraint ab_fk foreign key (col2)
references table_b (col4) INITIALLY DEFERRED DEFERRABLE;
alter table table_b add constraint ba_fk foreign key (col3)
references table_a (col1) INITIALLY DEFERRED DEFERRABLE;
The correct answer (although only recommended for the most assured of candidates):
Why are you asking me questions about a broken data model? Is this indicative of the sort of thing I'll be working with if I join your company?
Because this is a completely false situation. The two foreign keys operate to enforce a 1:1 relationship between table_a and table_b. So why are they two separate tables? Make them one and the problem goes away. This achieves the same thing:
alter table table_a add constraint ab_uk unique (col2);
drop table table_b;
Supposing there is a genuine need for two tables (i.e. if there are more columns than appear in this example) chose one table to be the parent and make the other one the child. Because as soon as we express the model that way we understand why it's so wrong: no child is its own parent, not even in the most twisted of sci-fi tales.
Simple just ensure that Col2 contains a value from Col4 of Table-B and that Col1 doesn't already exist in Table-A. Not knowing anything about the data types of the columns involved does make it more difficult, but since there doesn't seem to be an restrictions on how you get the data this might work:
insert into TableA select max(col1)||'0', max(col2) from TableA ;
This will work as long as col1 is either numeric or character based. It will likely fail if col1 is some other data type.

How to insert into a table considering that table has a Primary Key already in it?

I have two tables A and B and need to insert records (few columns not all) from A into B.
Of course I guess I can do:
INSERT INTO B (col2)
SELECT DISTINCT col2
FROM A
However, Col1 in table B (named ID) has a type of INT so it is causing this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'ID', table 'MyDB.dbo.Visitor'; column does not allow nulls. INSERT fails.
How can I make SQL Server ignore this column and just insert the data I need?
Thanks.
A primary key must fulfill two conditions:
It must be unique in the table (that is, any row in the table can be identified by its primary key), and
The fields that are part of the primary key cannot be NULL. That's because allowing NULL values in the primary key will make the uniqueness of the primary key impossible to hold, because a NULL value is non-equal to any other value, including another NULL.
Quoting from here:
A unique key constraint does not imply the NOT NULL constraint in practice. Because NULL is not an actual value (it represents the lack of a value), when two rows are compared, and both rows have NULL in a column, the column values are not considered to be equal. Thus, in order for a unique key to uniquely identify each row in a table, NULL values must not be used.
This should work assuming you don't insert duplicates into B:
INSERT INTO B (col2)
SELECT DISTINCT col2
FROM A
WHERE col2 IS NOT NULL
Set ID column in table B to "auto-increment".
SQL Server will provide automatically unique values for ID column if you define it as IDENTITY
In your case you can calculate the maximum value of ID column and start IDENTITY from the value that exceeds that maximum.
See the accepted answer for SQL Server, How to set auto increment after creating a table without data loss? for such code.
You need to create a relationship between the two tables and do an update statement.
Update table b set valueb = valuea from table a where a.id = b.id
You also need to rethink your design a little bit it sounds like.

Copy data from a table, into the same table with a different key

I was curious if it was possible to take data from a table, and duplicate it but assign a new primary key
for example, I wish to take data that has a column "question_id" which acts as the unique key for the table, and copy all of the data from the table with that question_id to the same table but with a new question_id.
any thoughts as to if this is possible using SQL?
my database is an ingres database
thanks in advance
Sure, something like this should work:
INSERT INTO YourTable (Question_Id, OtherField,...)
SELECT SomeNewQuestionId, OtherField,...
FROM YourTable
WHERE Question_Id = SomeQuestionId
Just replace SomeQuestionId and SomeNewQuestionId with the appropriate values.
It's a simple select query.
insert into mytable
(field2, field3, etc)
select field2, field3, etc
from mytable
where whatever.
This assumes that neither fields 2 nor 3 are the primary key, and that you have an autoincrement table.
Fast forward two years.... :)
I think this is the best and simplest way to do this. Inserting a row of data from the same table with a primary key will result in error because primary keys are unique for each row: Let question_id = 100.
INSERT INTO MyTable SELECT * FROM MyTable Where question_id=100;
In PostgreSQL:
ERROR: duplicate key value violates unique constraint "MyTable_pkey"
DETAIL: Key (question_id)=(100) already exists.
It is very simple to avoid the duplicate key value:
INSERT INTO MyTable SELECT (SELECT MAX(question_id)+1),Column1,Column2,etc FROM MyTable Where question_id=100;
By using MAX(question_id)+1, you are incrementing the maximum value of MyTable's question_id primary key, then add/copy the data to a new row with a unique question_id value.