SQL issue: Duplicate key value violates unique constraint - sql

I'm running Postgres10 on PGAdmin4
To see if my database is out of sync, I'm checking my primary key and primary key sequence.
I'm running this query to check primary key:
MAX(sid) FROM schema_name.table_name; Returns 1032
sid is the primary key
schema_name is the schema where my table is located
table_name is name of the table where the unique constraint is being violated
I'm running this query to check primary key sequence:
SELECT nextval(pg_get_serial_sequence('schema_name.table_name', 'sid')); returns 1042 (current value is 1041).
Referencing this SO: I'm referencing this stack overflow: postgresql duplicate key violates unique constraint
But the post is 9 years old and the solution only checks if the primary key's max is greater than the next value of the sequence (which it isn't in my case).

I have run into issues with a key being out of sync with a sequence when a custom program is inserting records records into a table and taking the last_key_value + 1 while another program is using the sequence nextval to insert into the same table.
This can create duplicate key problems.
I would check to make sure you don't have programs with this conflict.
A better way to fully circumvent this type of problem is to use an IDENTITY type column. Though I dont know if Postgres supports this data type.

Related

Primary key is not deleted when I deleted table inside SSMS- SQL Server

I have a table and I need to insert a huge number of records, so I create my table without primary key to make the insert faster. when I finished insert, I create primary key for that table using this command:
ALTER TABLE MyTable ADD CONSTRAINT PK_MyTable PRIMARY KEY (MyTableId)
The problem is if I delete the table inside SQL Server management studio then the next time when I want to create this primary key, it says :
The CREATE UNIQUE INDEX statement terminated because
a duplicate key was found for the object name
I need to let SQL knows that this primary key is connected to that table and must automatically be deleted when the table is being deleted.
I guess this is not a primary key problem. It is a problem with your data. You are not allowed to create a primary key because you have a duplicate value in your primary key column.
You could run a query to confirm that you have a duplicate.
SELECT
MyTableId,
COUNT(*)
FROM
MyTable
GROUP BY
MyTableId
HAVING
COUNT(*) > 1
The Best Answer to dropping the table containing Primary and foreign constraints is :
Step 1 : Drop the Primary key of the table.
Step 2 : Now it will prompt whether to delete all the foreign references or not.
Step 3 : Delete the table.

SQL Server assign negative PK values by default

When writing my thesis, I was writing a part about SQL data types and how to choose them wisely when designing a database structure.
I read somewhere that as a best practice you should not assign negative values to PK. this lead to the following question:
will an instance of SQL Server assign negative values to a Primary Key by default ? I know it is possible to assign them yourself, but I was wondering if SQL server will assign them by default and if so, in which cases?
I assume, but I've never tried, that if you create a primary key with a designation of IDENTITY(0,-1), it will auto assign descending values starting from 0
There lies a difference between Primary Key and Identity.Identity Property creates an identity column in a table with syntax:
IDENTITY [ ( seed , increment ) ]
where increment is the incremental value that is added to the identity value of the previous row that was loaded which can be + or - depending on the requirement.
and Primary Key is a column or combination of columns that contain values that uniquely identify each row in the table. It can be any set of columns other than the Identity column if they garuntees unique identification of rows in the table.
Coming back to the question a table can have only one PRIMARY KEY constraint, and a column that participates in the PRIMARY KEY constraint cannot accept null values. Because PRIMARY KEY constraints guarantee unique data, they are frequently defined on an identity column.
So SQL server don't assign any default value to a primary key as it's a constraint. When you specify a PRIMARY KEY constraint for a table, the Database Engine enforces data uniqueness by creating a unique index for the primary key columns.

Safely rename tables using serial primary key columns

I know that PostgreSQL tables that use a SERIAL primary key end up with an implicit index, sequence and constraint being created by PostgreSQL. The question is how to rename these implicit objects when the table is renamed. Below is my attempt at figuring this out with specific questions at the end.
Given a table such as:
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
value INTEGER
);
Postgres outputs:
NOTICE: CREATE TABLE will create implicit sequence "foo_pkey_seq" for serial column "foo.pkey"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
Query returned successfully with no result in 52 ms.
pgAdmin III SQL pane shows the following DDL script for the table (decluttered):
CREATE TABLE foo (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE foo OWNER TO postgres;
Now rename the table:
ALTER table foo RENAME TO bar;
Query returned successfully with no result in 17 ms.
pgAdmin III:
CREATE TABLE bar (
pkey integer NOT NULL DEFAULT nextval('foo_pkey_seq'::regclass),
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
Note the extra DEFAULT nextval('foo_pkey_seq'::regclass), this means that renaming the table does not rename the sequence for the primary keys but now we have this explicit nextval().
Now rename the sequence:
I want to keep the database naming consistent so I tried:
ALTER SEQUENCE foo_pkey_seq RENAME TO bar_pkey_seq;
Query returned successfully with no result in 17 ms.
pgAdmin III:
CREATE TABLE bar (
pkey serial NOT NULL,
value integer,
CONSTRAINT foo_pkey PRIMARY KEY (pkey )
);
ALTER TABLE bar OWNER TO postgres;
The DEFAULT nextval('foo_pkey_seq'::regclass), is gone.
QUESTIONS
Why did the DEFAULT nextval('foo_pkey_seq'::regclass) statement appear and disappear?
Is there a way to rename the table and have the primary key sequence renamed at the same time?
Is it safe to rename the table then sequence while clients are connected to the database, are there any concurrency issues?
How does postgres know which sequence to use? Is there a database trigger being used internally? Is there anything else to rename other than the table and the sequence?
What about the implicit index created by a primary key? Should that be renamed? If so, how can that be done?
What about the constraint name above? It is still foo_pkey. How is a constraint renamed?
serial is not an actual data type. The manual states:
The data types smallserial, serial and bigserial are not true types,
but merely a notational convenience for creating unique identifier columns
The pseudo data type is resolved doing all of this:
create a sequence named tablename_colname_seq
create the column with type integer (or int2 / int8 respectively for smallserial / bigserial)
make the column NOT NULL DEFAULT nextval('tablename_colname_seq')
make the column own the sequence, so that it gets dropped with it automatically
The system does not know whether you did all this by hand or by way of the pseudo data type serial. pgAdmin checks on the listed features and if all are met, the reverse engineered DDL script is simplified with the matching serial type. If one of the features is not met, this simplification does not take place. That is something pgAdmin does. For the underlying catalog tables it's all the same. There is no serial type as such.
There is no way to automatically rename owned sequences. You can run:
ALTER SEQUENCE ... RENAME TO ...
like you did. The system itself doesn't care about the name. The column DEFAULT stores an OID ('foo_pkey_seq'::regclass), you can change the name of the sequence without breaking that - the OID stays the same. The same goes for foreign keys and similar references inside the database.
The implicit index for the primary key is bound to the name of the PK constraint, which will not change if you change the name of the table. In Postgres 9.2 or later you can use
ALTER TABLE ... RENAME CONSTRAINT ..
to rectify that, too.
There can also be indexes named in reference to the table name. Similar procedure:
ALTER INDEX .. RENAME TO ..
You can have all kinds of informal references to the table name. The system cannot forcibly rename objects that can be named anything you like. And it doesn't care.
Of course you don't want to invalidate SQL code that references those names. Obviously, you don't want to change names while application logic references them. Normally this wouldn't be a problem for names of indexes, sequences or constraints, since those are not normally referenced by name.
Postgres also acquires a lock on objects before renaming them. So if there are concurrent transaction open that have any kind of lock on objects in question, your RENAME operation is stalled until those transactions commit or roll back.
System catalogs and OIDs
The database schema is stored in tables of the system catalog in the system schema pg_catalog. All details in the manual here. If you don't know exactly what you are doing, you shouldn't be messing with those tables at all. One false move and you can break your database. Use the DDL commands Postgres provides.
For some of the most important tables Postgres provides object identifier types and type casts to get the name for the OID and vice versa quickly. Like:
SELECT 'foo_pkey_seq'::regclass
If the schema name is in the search_path and the table name is unique, that gives you the same as:
SELECT oid FROM pg_class WHERE relname = 'foo_pkey_seq';
The primary key of most catalog tables is oid and internally, most references use OIDs.

postgresql: error duplicate key value violates unique constraint

This question have been asked by several people but my problem seems to be different.
Actually I have to merge same structured tables from different databases in postgresql into a new DB. What I am doing is that I connect to remote db using dblink, reads that table in that db and insert it into the table in the current DB like below
INSERT INTO t_types_of_dementia SELECT * FROM dblink('host=localhost port=5432 dbname=snap-cadence password=xxxxxx', 'SELECT dementia_type, snapid FROM t_types_of_dementia') as x(dementia_type VARCHAR(256),snapid integer);
First time this query runs fine, but when I run it again or try to run it with some other remote database's table: it gives me this error
ERROR: duplicate key value violates unique constraint
"t_types_of_dementia_pkey"
I want that this new tables gets populated by entries of others tables from other dbs.
Some of the solutions proposed talks about sequence, but i am not using any
The structure of the table in current db is
CREATE TABLE t_types_of_dementia(
dementia_type VARCHAR(256),
snapid integer NOT NULL,
PRIMARY KEY (dementia_type,snapid)
);
P.S. There is a specific reason why both the columns are used as a primary key which may not be relevant in this discussion, because same issue happens in other tables where this is not the case.
As the error message tells you - you can not have two rows with the same value in the columns dementia_type, snapid since they need to be unique.
You have to make sure that the two databases has the same values for dementia_type, snapid.
A workaround would be to add a column to your table alter table t_types_of_dementia add column id serial generated always and use that as primary key instead of your current.

SQL Server 2008: The columns in table do not match an existing primary key or unique constraint

I need to make some changes to a SQL Server 2008 database.
This requires the creation of a new table, and inserting a foreign key in the new table that references the Primary key of an already existing table. So I want to set up a relationship between my new tblTwo, which references the primary key of tblOne.
However when I tried to do this (through SQL Server Management Studio) I got the following error:
The columns in table 'tblOne' do not
match an existing primary key or
UNIQUE constraint
I'm not really sure what this means, and I was wondering if there was any way around it?
It means that the primary key in tblOne hasn't been properly declared - you need to go to tblOne and add the PRIMARY KEY constraint back onto it.
If you're sure that tblOne does have a PRIMARY KEY constraint, then maybe there are multiple tblOne tables in your DB, belonging to different schemas, and your references clause in your FK constraint is picking the wrong one.
If there's a composite key (which your comment would indicate), then you have to include both columns in your foreign key reference also. Note that a table can't have multiple primary keys - but if it has a composite key, you'll see a key symbol next to each column that is part of the primary key.
If you have a composite key the order is important when creating a FK, and sometimes the order is not how it is displayed.
What I do is go to the Keys section of the table1 and select script primary key as create to clipboard and then create FK using the order as shown in script
I've had this situation that led me to this topic. Same error but another cause. Maybe it will help someone.
Table1
ColA (PK)
ColB (PK)
ColC
Table2
ID (PK)
ColA
COLB
When trying to create foreign key in Table2 I've choose values from combobox in reverse order
Table1.ColB = Table2.ColB
Table1.ColA = Table2.ColA
This was throwing me an error like in topic name. Creating FK keeping order of columns in Primary key table as they are, made error disappear.
Stupid, but.. :)
If you still get that error after you have followed all advice from the above answers and everything looks right.
One way to fix it is by Removing your Primary keys for both tables, Save, Refresh, and add them again.
Then try to add your relationship again.
This Error happened with me When I tried to add foreign key constraint starting from PrimaryKey Table
Simpy go to other table and and create this foreign key constraint from there (foreign key Table)
This issue caught me out, I was adding the relationship on the wrong table. So if you're trying to add a relationship in table A to table B, try adding the relationship in table B to table A.
That looks like you are trying to create a foreign key in tblTwo that does not match (or participate) with any primary key or unique index in tblOne.
Check this link on MSDN regarding it. Here you have another link with a practical case.
EDIT:
Answwering to your comment, I understand you mean there are 2 fields in the primary key (which makes it a composite). In SQL it is not possible to have 2 primary keys on the same table.
IMHO, a foreign key field should always refer to a single register in the referenced table (i.e. the whole primary key in your case). That means you need to put both fields of the tblOne primary key in tblTwo before creating the foreign key.
Anyway, I have investigated a bit over the Internet and it seems SQL Server 2008 (as some prior versions and other RDBMS) gives you the possibility to reference only part of the primary key as long as this part is a candidate key (Not Null and Unique) and you create an unique constraint on it.
I am not sure you can use that in your case, but check this link for more information on it.
I have found that the column names must match.
Example:
So if tblOne has id called categoryId a reference in tblTwo must also be called categoryId.
_tblname, primary key name, foreign key_
tblOne, "categoryId", none
tblTwo, "exampleId", "categoryId"
I noticed this when trying to create foreign key between 2 tables that both had the column name "id" as primary key.
If nothing helps, then this could be the reason:
Considering this case:
Table A:
Column 1 (Primary Key)
Column 2 (Primary Key)
Column 3
Column 4
Table B:
Column a (Primary Key)
Column b
Column c
when you are defining a dependency B to A, then you are forced to respect the order in which the primaries are defined.
That's mean your dependency should look like this:
Table A Table B
Column 1 Column b
Column 2 Column c
AND NOT:
Table A Table B
Column 2 Column c
Column 1 Column b
then this will lead to the error you are encountering.
I've found another way to get this error. This can also happen if you are trying to make a recursive foreign key (a foreign key to the primary key in the same table) in design view in SQL Management Studio. If you haven't yet saved the table with the primary key it will return this message. Simply save the table then it will allow you to create the foreign key.
If you have data in your tables this could be the issue.
In my case I had some data in the Account table that I loaded at 3 pm, and some data in Contact table that I loaded at 3:10 pm, so Contact table had some values that weren't in my Account table yet.
I ended up deleting these values from the contact table and then managed to add a key without any problems.
Kindly also see that there are no existing data inside the table where the primary key is defined while setting the foreign key with another table column.
this was the cause of the error in my case.
I had to take backup empty the table set the relationship and then upload the data back.
sharing my experience
Was using ms sql smss