How to turn a Unique Constraint into a Primary key in PostgreSQL? - sql

i have a table that has a primary key on some columns, and another unique constraint on another column. I dropped the old primary key, and now want to make the existing unique constraint the new primary key of the table, without dropping/rebuilding it from scratch.
The situation right now is like this:
Indexes:
"t_review_routing_id_key" UNIQUE CONSTRAINT, btree (id)
When I run:
ALTER TABLE t_review_routing ADD PRIMARY KEY USING INDEX t_review_routing_id_key;
It says:
ERROR: index "t_review_routing_id_key" is already associated with a constraint
LINE 1: ALTER TABLE t_review_routing ADD PRIMARY KEY USING INDEX t_r...
I also tried ALTER TABLE t_review_routing ADD CONSTRAINT t_review_routing_id_pkey PRIMARY KEY USING INDEX t_review_routing_id_key;, same error.
Any ideas?

You can drop your already existing constraint before creating the new one, but dropping the constraint will make the index disappear too.
But, you can create a new index CONCURRENTLY (example from the docs):
CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
This method is explicitly mentioned at the docs of ALTER TABLE ... ADD table_constraint_using_index.

Related

Drop unique index when having Primary Key index

I have the following table
CREATE TABLE steps (
hash_id text UNIQUE PRIMARY KEY,
depth integer
);
-- Indices -------------------------------------------------------
CREATE UNIQUE INDEX steps_hash_id_key ON steps(hash_id text_ops);
CREATE UNIQUE INDEX steps_pkey ON steps(hash_id text_ops);
But I'd like to remove the redundant UNIQUE index because PRIMARY KEY is already unique.
I've also many other tables linked to the hash_id of my steps table with foreign keys.
When I try to remove my UNIQUE index like this:
ALTER TABLE steps DROP CONSTRAINT steps_hash_id_key;
I get
ERROR: cannot drop constraint steps_hash_id_key on table steps because other objects depend on it
DETAIL: constraint steps_routes_step_hash_id_fkey on table steps_routes depends on index steps_hash_id_key
constraint steps_likes_dislikes_step_hash_id_fkey on table steps_likes_dislikes depends on index steps_hash_id_key
HINT: Use DROP ... CASCADE to drop the dependent objects too.
The matter is that I don't want to cascade delete anything, I'd just like to remove this duplicated unique index. Is it possible ?
Thanks to the discussion in comments (#Gordon Linoff) here's a way to fix this issue:
Drop foreign keys
Drop Primary Keys and Unique Keys
Recreate Primary Key only
Recreate Foreign Keys
ALTER TABLE steps_routes DROP CONSTRAINT steps_routes_step_hash_id_fkey;
ALTER TABLE steps_likes_dislikes DROP CONSTRAINT steps_likes_dislikes_step_hash_id_fkey;
ALTER TABLE steps DROP CONSTRAINT steps_pkey;
ALTER TABLE steps DROP CONSTRAINT steps_hash_id_key;
ALTER TABLE steps ADD PRIMARY KEY (hash_id);
ALTER TABLE steps_routes ADD FOREIGN KEY (step_hash_id) REFERENCES steps(hash_id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE steps_likes_dislikes ADD FOREIGN KEY (step_hash_id) REFERENCES steps(hash_id) ON DELETE CASCADE ON UPDATE CASCADE;

Oracle SQL : Cannot create a foreign key based on index of more than one column

I'm not able to create a foreign key based on index of more than one column.
Adding the foreign key returns the error :
ORA-02270: no matching unique or primary key for this column-list.
Below the code :
CREATE TABLE test_ek_uk (NOOPER VARCHAR2(7) NOT NULL
,NUMSEQ NUMBER NOT NULL
,ANY_TEXT VARCHAR2(4000));
CREATE UNIQUE INDEX test_ek_uk_nooper_numseq ON test_ek_uk (NOOPER, NUMSEQ);
CREATE TABLE test_ek_fk (ID NUMBER UNIQUE NOT NULL, NOOPER VARCHAR2(7), NUMSEQ number);
ALTER TABLE test_ek_fk ADD CONSTRAINT test_ek_fk_FK FOREIGN KEY (NOOPER, NUMSEQ) REFERENCES test_ek_uk (NOOPER, NUMSEQ);
A Foreign Key references either a Primary Key constraint or a Unique constraint. And it must be a constraint, a unique index is not enough.
If you already have index then you can create unique constraint based on that index. For your case:
alter table test_ek_uk
add constraint test_ek_uk_nooper_numseq unique (NOOPER, NUMSEQ)
using index altest_ek_uk_nooper_numseq;
But if you don't have that index - there is no need to create it explicitly.
So, instead of creating the unique index you could create a unique constraint:
alter table test_ek_uk
add constraint test_ek_uk_nooper_numseq unique (NOOPER, NUMSEQ);
The unique index is created in the background when you create this unique constraint.

Change clustered index without touching primary key

we have an existing database where we would like to change the clustered index to a unique, monotonically increasing field (as it should have been from the start), but we don't want to change the primary key because there is data referencing this primary key.
We have added a new column SequentialId and populated it with data, to serve as our new clustered index.
But how do we change the clustered index? If possible, we would like to either replace the existing clustered index OR add SequentialId to the current index as the first column.
How do we go about this? It seems we cannot change the clustered index without dropping the primary key (which we can't do).
Using the ALTER TABLE command drop the PRIMARY KEY constraint, which is not the same as dropping the CLUSTERED INDEX that is enforcing the PRIMARY KEY contraint, and recreate with the additional columns
ALTER TABLE <Table_Name>
DROP CONSTRAINT <constraint_name>
ALTER TABLE <Table_Name>
ADD CONSTRAINT <constraint_name> PRIMARY KEY (<Column1>,<Column2>)

Cannot find primary key column in table

I added a constraint primary key to my table and the query ran successfully. The dilemma I am facing is I cannot locate the primary key column in my table.
ALTER TABLE salesdata
ADD CONSTRAINT pk_salesdata PRIMARY KEY( "Address_of_New_Home","Sq_Ft","Build_Spec", "Realtor_Sale","Can","Actual_Sale_Date")
When I do:
select * from salesdata
It shows all the columns from before and no primary key column (pk_salesdata).
And even more baffling is when:
select pk_salesdata from salesdata
Database shows:
ERROR: column "pk_salesdata" does not exist
I want to add primary key column to the table. I humbly request assistance of databasers.
You create PRIMARY KEY, but...
you create composed primary key from columns "Address_of_New_Home", "Sq_Ft", "Build_Spec", "Realtor_Sale", "Can", "Actual_Sale_Date" - it is not good idea
your primary key have an alias name pk_salesdata, but it's only constraint name
you didn't create new column
If you would like new synthetic primary key column you have to use command:
ALTER TABLE salesdata ADD COLUMN mynewautoincrementid SERIAL PRIMARY KEY;
Primary Kay it's constraint in table when you add a primary key to any column you can select column name to show data
It looks like you've wrapped the columns you want to include in your primary keys in double quotes. That's not how this command works. Drop the quotes re-run the command and see what happens.
ALTER TABLE salesdata
ADD CONSTRAINT pk_salesdata PRIMARY KEY( Address_of_New_Home,Sq_Ft,Build_Spec, Realtor_Sale,Can,Actual_Sale_Date)
It might be easier to add a primary index through the SQL GUI.
Here's the MS documentation page for creating a primary key.
https://msdn.microsoft.com/en-us/library/ms189039.aspx
Note: Since your adding a primary key don't expect it to be available as a column.

Change Primary Key

I have a table in Oracle which has following schema:
City_ID Name State Country BuildTime Time
When I declared the table my primary key was both City_ID and the BuildTime, but now I want to change the primary key to three columns:
City_ID BuildTime Time
How can I change the primary key?
Assuming that your table name is city and your existing Primary Key is pk_city, you should be able to do the following:
ALTER TABLE city
DROP CONSTRAINT pk_city;
ALTER TABLE city
ADD CONSTRAINT pk_city PRIMARY KEY (city_id, buildtime, time);
Make sure that there are no records where time is NULL, otherwise you won't be able to re-create the constraint.
You will need to drop and re-create the primary key like this:
alter table my_table drop constraint my_pk;
alter table my_table add constraint my_pk primary key (city_id, buildtime, time);
However, if there are other tables with foreign keys that reference this primary key, then you will need to drop those first, do the above, and then re-create the foreign keys with the new column list.
An alternative syntax to drop the existing primary key (e.g. if you don't know the constraint name):
alter table my_table drop primary key;
Sometimes when we do these steps:
alter table my_table drop constraint my_pk;
alter table my_table add constraint my_pk primary key (city_id, buildtime, time);
The last statement fails with
ORA-00955 "name is already used by an existing object"
Oracle usually creates an unique index with the same name my_pk. In such a case you can drop the unique index or rename it based on whether the constraint is still relevant.
You can combine the dropping of primary key constraint and unique index into a single sql statement:
alter table my_table drop constraint my_pk drop index;
check this:
ORA-00955 "name is already used by an existing object"