I'm trying (SQL Server Compact) to add primary key constraint on existing table that has some rows in it. While adding primary key I'm getting the error:
"A duplicate key cannot be inserted into a unique index"
I don't what this is, can anyone help me with this?
Make sure the data in the table respects the contraint you're trying to set on the table. If the column you are making primary has duplicate entries, it won't be able to work as primary key, hence the error.
You could try and find the rows with duplicate entries, with something like this:
select Id, Count(*) from myTable
having Count(*) > 1
group by Id
Try this
select id_column, count(*) from your_table group by id_column having count(*) > 1
If there are any records returned from this above query you cannot add a primary key on id_column since duplicate IDs exist.
Of course you will need to replace id_column and your_table with the appropriate names.
Related
I use the MS Sync Framework to sync my SQL Server instance with a local SQL CE file to make it possible working offline with my Windows app.
I use GUIDs as keys. On my table I have a unique index on 2 columns: user_id and setting_id:
usersettings table
------------------
id PK -> I also tried it without this column. Same result
user_id FK
setting_id FK
value
Now I do the following:
I create a new record in this table in both databases - SQL Server and SQL CE with the same user_id and setting_id.
This should work and merge the data together since this can happen in real life. But I get an error when syncing saying the unique key constraint led to an error. The key pair already exists in the table.
A duplicate value cannot be inserted into a unique index. [ Table name = user_settings,Constraint name = unique_userid_settingid ]
Why can't MS sync handle that? It should not try to insert the key pair again. It should update the value if needed.
The issue is if you add the same key pair to different copies of the table, they get different IDs (GUIDs) as primary keys in this usersettings table.
As this is simply a many-to-many table between Users and Settings, there is no need to have that ID as a PK (or even a column at all).
Instead, just use a concatenated key of the two FKs e.g.,
CREATE TABLE [dbo].[usersettings](
[user_id] [UNIQUEIDENTIFIER] NOT NULL,
[setting_id] [UNIQUEIDENTIFIER] NOT NULL,
[value] [varchar](50) NOT NULL,
CONSTRAINT [PK_usersettings] PRIMARY KEY CLUSTERED ([user_id] ASC, [setting_id] ASC) );
Of course, include appropriate field settings (e.g., if you use VARCHARs to store the IDs) and relevant FKs.
As the rows inserted should now be identical on the two copies, it should merge fine.
If you must have a single column as a unique identifier for the table, you could make it meaningful e.g.,
the PK (ID) becomes a varchar (72)
it gets filled with CONCAT(user_ID, setting_id)
As the User_ID and Setting_ID are FKs, you should already have them generated so concatenating them should be easy enough.
Do you get the error during sync, then it should appear as a conflict, that you must solve in code.
https://learn.microsoft.com/en-us/previous-versions/sql/synchronization/sync-framework-2.0/bb734542(v=sql.105)
I also see this in the manual: By default, the following objects are not copied to the client database: FOREIGN KEY constraints, UNIQUE constraints, DEFAULT constraints, and the SQL Server ROWGUIDCOL property. This indicates poor support for your scenario
I suggest you remove the unique constraint from the device table.
I have a application where users can add update and delete a record, I wanted to know the best ways to avoid duplicate records. In this application to avoid duplicate records i created a index on the table, is it a good practice or there are others?
There are a few ways to do this. If you have a unique index on a field and you try to insert a duplicate value SQL Server with throw an error. My preferred way is to test for existence before the insert by using
IF NOT EXISTS (SELECT ID FROM MyTable WHERE MyField = #ValueToBeInserted)
BEGIN
INSERT INTO MyTable (Field1, Field2) Values (#Value1, #Value2)
END
You can also return a value to let you know if the INSERT took place using an ELSE on the above code.
If you choose to index a field you can set IGNORE_DUP_KEY to simply ignore any duplicate inserts. If you were inserting multiple rows any duplicates would be ignored and the non duplicates would continue to be inserted.
You can use UNIQUE constraints on columns or on a set of columns that you don't want to be duplicated; see also http://www.w3schools.com/sql/sql_unique.asp.
Here is an example for both a single-column and a multi-column unique constraint:
CREATE TABLE [Person]
(
…
[SSN] VARCHAR(…) UNIQUE, -- only works for single-column UNIQUE constraint
…
[Name] NVARCHAR(…),
[DateOfBirth] DATE,
…
UNIQUE ([Name], [DateOfBirth]) -- works for any number of columns
)
An id for a table is almost compulsory according to me. To avoid duplicates when inserting a row, you can simply use :
INSERT IGNORE INTO Table(id, name) VALUES (null, "blah")
This works in MySQL, i'm not sure about SQL Server.
I have a table in SQL Server called Test_Table with two columns: ID and Name
The table looks something like this:
ID NAME
--------
1 John
2 Jane
Now I have a stored procedure which inserts records into this.
INSERT INTO Test_Table
VALUES (#Id,#Name)
And I'm passing this values from my c# code. Now I want to modify this so that the table does not have duplicates. Where should I check this, In the code or the DB? I'm very weak in DB side stuff. So how can I handle duplicates before inserting values in my table
The "right" way to do that is in DB because:
Don't need to read all DB
Need to pass all data to C# which increase the IO
Concurrency - if you have more than 1 C# application you will need to sync them vs in DB it would be simpler
You can define the column as unique or key, which will prevent duplicate values ,DB will take care of it
If you use MSSQL use UNIQUE Constraints
Read this good answer about avoid duplicates
You should do this check in the database. Always, if you want it to be true of the data.
I'm not sure what you consider a duplicate. Normally, an id column would be an identity column that is automatically incremented for each value. This would prevent duplicates. You would define it as:
create table test_table (
id int not null identity(1, 1),
. . .
Then, you would insert into it using:
insert into test_table(name)
values (#Name);
The id would be assigned automatically.
If you want no duplicates just for name, then create a unique index or unique constraint (really the same thing). You can do this in the table definition just by adding unique to the column:
create table test_table (
id int not null identity(1, 1),
name varchar(255) unique
. . .
Or by creating a unique index after you have created the table:
create index test_table_name on test_table(name)
(Or by explicitly creating a constraint, which is another method.)
In either case ,you will have to access to database to check wheteher values exist already.
IF NOT EXISTS (SELECT * FROM Test_Table WHERE ID= #ID AND Name=#Name)
BEGIN
INSERT INTO Test_Table
VALUES (#Id,#Name)
END
If it is possible to make ID column as unique you can avoid checking as insertion would.t be allowed for repeating ID values , in that case you will have to handle error.
See this thread how to handle violation of Unique key constraint.
If you don't want repeating IDs you'll have to set the ID as the Primary Key, which is pretty much obligatory.
If you don't want the Name to repeat, you could populate a list with the Names the table contains, and then you would only insert whatever name is not in that List.
Here is an example, instead of using a list I used a dictionary:
Dictionary<int, string> Names = new Dictionary<int, string> ();
using (SqlCommand command = new SqlCommand ("SELECT * FROM TestTable", con))
using (SqlDataReader reader = command.ExecuteReader ()) {
while (reader.Read ()) {
Names.Add (reader["ID"], reader["NAME"]);
}
}
if (!Names.ContainsValue ("ValueYouWantToInsert")) {
//do stuff
}
You should check it in DB, Also you can make ID as Primary Key
Which is mostly used, because people can have duplicate name.
You can modify your Id with the Unique key constraint or you can also make it Primary key.
Try like this:
alter table Test_Table add primary key (ID)
and
alter table Test_Table add unique key (Name)
IF NOT EXISTS (SELECT * FROM Test_Table WHERE ID= #ID AND Name=#Name)
BEGIN
INSERT INTO Test_Table
VALUES (#Id,#Name)
END
ELSE
BEGIN
UPDATE Test_Table
SET ID= #ID,NAME = #Name
WHERE ID= #ID AND Name=#Name
END
I am building an API with OrmLite from ServiceStack.
When populating it with test data I get the following error:
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_Order_Customer_CustomerId". The conflict occurred in database
"C:\USERS\ALECTAYLOR\SOCIALBOOTSTRAPAPI\SRC\SOCIALBOOTSTRAPAPI\APP_DATA\USERAUTH.MDF",
table "dbo.Customer", column 'Id'. The statement has been terminated.
Code (lines 213-236 + CreateOrders function): http://pastebin.com/Njhz7sD2
Profiler output: http://fiddle.jshell.net/cTen2/1/show/
Thanks for any advice on how to rectify this issue.
FOREIGN KEY constraint generally means that you are trying to insert a value into a table that doesn't exist in the reference table. Take a look at MSDN article on Foreign Keys for more info about what they are and how they work. You need to have a look at the actual structure of the data tables order and customer.
I would guess that you are inserting a customerId into the orders table that doesn't exist in the customers table.
since this is the insert that's failing, the only logical explanation is that customer number 1 doesn't exist. I saw that you insert 3 customers a few lines before. Maybe the transaction was not committed between the moment the customers were inserted and the order is inserted.
INSERT INTO "Order" ("CustomerId", "ShopId", "ShippingAddress",
"OrderDate", "RequiredDate", "ShippedDate", "Total") VALUES (1, 0,
'{line1:440 Crescent St, line2:South Melbourne, postCode:7416,
city:Melbourne, country:Australia}', '20120430 07:43:18.686', NULL,
NULL, 0);
Try to commit the insert after you insert the clients and before you insert the orders
Alright, got it to work.
Needed to set the ShopId of Order and orderId of the orderDetails List.
http://pastebin.com/TbrW150T
I have a table A with columns Aname , Work
create table A(Aname varchar(40) , Work varchar(40) )
The table already has the below data inserted:
INSERT INTO A VALUES ('GREAME ','PLAYER')
Aname || Work
GREAME PLAYER
now i want that when i insert a new record, Aname--GREAME , Work---SALESMAN, then it is
inserted , but if i insert this : Aname--GREAME Work--PLAYER again, then it is not inserted
I want this:
Aname || Work
GREAME PLAYER
GREAME PLAYER --- COULD NOT BE INSERTED
GREAME SALESMAN --- COULD BE INSERTED
That is , the Work column checks for uniqueness when the to be inserted value of Aname
already exists.
How do i implement this? Please help with code.
EDIT------
in the insert query, the Aname column would be picked up from another table B
then how do i do it?
A unique constraint or a primary key will prevent you from insert with an error/exception. This insert will just not insert the row it it already exists.
insert into A (Aname, Work)
select 'GREAME', 'PLAYER'
where not exists (select *
from A
where Aname = 'GREAME' and Work = 'PLAYER')
And if you need the combination of AName and Work to be Unique then
ALTER TABLE A ADD CONSTRAINT U_NameWork UNIQUE(AName, Work)
But if you need AName to be Unique irrespective of Work then
ALTER TABLE A ADD CONSTRAINT U_Name UNIQUE(AName)
Edit: As per SanjeevKumar, making (AName, Work) a composite PRIMARY KEY will also work provided you have no other PK, although you might also consider a surrogate PK.