In PG:
I made a user table that includes unique emails, but later decided that emails should not be unique. I pushed changes to make my email field non-unique (I use an ORM, so I don't actually have the exact SQL that took place), but PG still won't let me use duplicate email addresses.
I checked the index and it's not unique, but there's a constraint keeping me from having duplicate email addresses. However I'm having trouble dropping this constraint. What am I doing wrong?
SQL> ALTER TABLE "users" DROP CONSTRAINT "unique_users_email"
PGError: ERROR: constraint "unique_users_email" of relation "users" does not exist
SQL> UPDATE users SET email = 'test#test.com'
PGError: ERROR: duplicate key value violates unique constraint "unique_users_email"
DETAIL: Key (email)=(test#test.com) already exists.
I bet that "unique_users_email" is actually the name of a unique index rather than a constraint. Try:
DROP INDEX "unique_users_email";
Recent versions of psql should tell you the difference between a unique index and a unique constraint when looking at the \d description of a table.
Related
I have a table which has a UNIQUE INDEX on 6 different columns. However, there are duplicates in the table. When I drop the index and try to re-create it, it throws error saying there are duplicate values.
Is there a way in which I can have the duplicate rows and still create the unique index ?
I see that there are NOVALIDATE options for constraints. Is there anything similar for Indexes.
I am guessing there should be a way since there duplicate rows in the table with a valid UNIQUE INDEX.
Kindly assist.
You can create a UNIQUE index on your table, even if it has duplicates, if you mark the index as UNUSABLE. This means that the index will exist but the system can't make use of it. To do so use a command similar to
CREATE UNIQUE INDEX UNUSABLE_UNIQUE_IDX_SUCCEEDS
ON TABLE_WITH_DUPS(ID)
UNUSABLE
db<>fiddle here
CREATE INDEX docs here
As if you don't want to get error ORA-00001 Unique constraint violated error during multiple insert operations even violation occurs unless the inserted data commited. Then you can make the unique key deferrable initially deferred such as
alter table tab
drop constraint Ukey [cascade];
alter table tab
add constraint Ukey unique ( col1, col2, ..., col6 )
deferrable initially deferred
the above cascade option is related to removing the unique key even if there exist foreign keys in the child tables of the table tab.
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.
Suppose user name and phone number should be unique at the time of table define without using unique constraint and check constraint in sql server.i don't want to create sp for that.please suggest any otherway to prevent duplicate column in sql server r2 2008. Il
One correct way (and really the best way) is to use a unique constraint. It is unclear whether you want one or two constraints, based on your description. If you don't want a unique constraint, you should explain why not.
That is, if you want the pair to be unique:
alter table add constraint unq_t_username_phonenumber unique (username, phonenumber);
Or you want each one to be unique:
alter table add constraint unq_t_username unique (username);
alter table add constraint unq_t_phonenumber unique (phonenumber);
When you define the table, you can also do one-column unique constraints in-line:
create table . . . (
. . .,
UserName varchar(255) not null unique,
. . .
);
Almost equivalent to a unique constraint is a unique index:
create unique index unq_t_username on t(username);
The difference is that you can name the constraint. This name is handy when a violation occurs, because the constraint name (but not index name) is typically in the message.
I have following indexes/unique constraints in my table.
INDNAME COLNAMES
SQL160215110206240 +ID
SQL160215110206360 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME
SQL160215145445420 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME+PROVISIONING_CONFIG_ID
Now I run following code segment on my darabase.
BEGIN
DECLARE v_rcount VARCHAR(128);
DECLARE STMT VARCHAR(200);
select INDNAME into v_rcount from SYSCAT.INDEXES WHERE TABNAME='IDP_PROVISIONING_ENTITY' AND COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME';
SET STMT = 'ALTER TABLE IDP_PROVISIONING_ENTITY DROP CONSTRAINT ' || v_rcount;
PREPARE S1 FROM STMT;
EXECUTE S1;
END
When I run it for the 1st time, I am getting following response.
DB20000I The SQL command completed successfully.
But when I list the indexes of the table, I am still seeing all 3 indexes as before.
And also when I run the same code segment again, I am getting following error.
SQL0204N "SQL160215110206360" is an undefined name. SQLSTATE=42704
Not only this index, if I try to drop any other index in the same database, I am getting the same error. What is the reason for this? How can I solve this?
The cause for this issue is, I am getting the name from SYSCAT.INDEXES. So there it is returning the name of INDEX. Even though a INDEX is created to each unique constraint, name of index can be different from name of Constraint. So here I have dropped the constraint and then I have checked the index table if it has removed. That's the reason why I can see the same index name still after removing the constraint.
Also every index name in SYSCAT.INDEXES will not refer to a constraint. So everytime I run DROP CONSTRAINT with a name from SYSCAT.INDEXES will not return success.
IBM DB2 behaves little bit differently compared to other well known databases when comes to constraints and indexes. So let me explain the solution for your problem in detail.
You have the following table.
CREATE TABLE IDP_PROVISIONING_ENTITY (
ID INTEGER NOT NULL,
PROVISIONING_CONFIG_ID INTEGER NOT NULL,
ENTITY_TYPE VARCHAR(255) NOT NULL,
ENTITY_LOCAL_USERSTORE VARCHAR(255) NOT NULL,
ENTITY_NAME VARCHAR(255) NOT NULL,
ENTITY_VALUE VARCHAR(255) NOT NULL,
TENANT_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE),
FOREIGN KEY (PROVISIONING_CONFIG_ID) REFERENCES IDP_PROVISIONING_CONFIG(ID) ON DELETE CASCADE)
/
It has a primary key and two unique constraints. The DB2 will automatically create indexes for these three constraints.
The problem is, we have not defined the constraints as named constraints. Therefore we have to take an extra effort to find out the names of the indexes and the constraints which are auto generated by DB2.
These are the two unique constraints that we have in the table.
UNIQUE (ENTITY_TYPE, TENANT_ID, ENTITY_LOCAL_USERSTORE, ENTITY_NAME),
UNIQUE (PROVISIONING_CONFIG_ID, ENTITY_TYPE, ENTITY_VALUE)
You can find the auto generated names for the unique constraints by running the following query. the constraintyp='U' for unique constraints and it is 'P' for primary keys.
db2 "select NAME from sysibm.systabconst where tbname='IDP_PROVISIONING_ENTITY' and constraintyp='U'"
NAME
--------
SQL160219074557840
SQL160219074557920
Above is the result I got. You will get different values in your database as these are random generated.
You can run the following query to see the indexes created for the IDP_PROVISIONING_ENTITY' table.
db2 "SELECT NAME, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY'"
NAME COLNAMES
SQL160219074557290 +ID
SQL160219074557790 +PROVISIONING_CONFIG_ID+ENTITY_TYPE+ENTITY_VALUE
SQL160219074557860 +ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME
Now we know the constraint names for the two unique constraints and the index names for the IDP_PROVISIONING_ENTITY table.
You can find the particular index you need to drop by adding a where clause for the above query as below.
db2 "SELECT NAME FROM SYSIBM.SYSINDEXES WHERE TBNAME='IDP_PROVISIONING_ENTITY' and COLNAMES='+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME'"
NAME
----------
SQL160219074557860
In IBM DB2, you cannot drop an index which is generated for a constraint (primary key or unique) directly. For that, you need to drop the constraint which will drop the index also.
But the problem is we do not know what is the name of the unique constraint that is associated with the index "+ENTITY_TYPE+TENANT_ID+ENTITY_LOCAL_USERSTORE+ENTITY_NAME". We already know that the index name we need to drop is SQL160219074557860.
You can find it out which constraint is associated with which index by running the following query.
db2 "select CONSTNAME, BNAME from SYSCAT.CONSTDEP where TABNAME = 'IDP_PROVISIONING_ENTITY'"
CONSTNAME BNAME
SQL160219074557790 SQL160219074557290
SQL160219074557840 SQL160219074557790
SQL160219074557920 SQL160219074557860
Based on the results, you can get to know the name of the constraint.
So the constraint name associated with the index name "SQL160219074557860" is "SQL160219074557920".
So since we know the constraint name now, we can drop the unique constraint.
db2 "ALTER TABLE IDP_PROVISIONING_ENTITY DROP UNIQUE SQL160219074557920"
This will drop the constraint as well as the index created for the constraint.
I'm having an issue trying to re-enable a unique constraint. I try using this command:
alter table TESTSCHEMA_1.TEST_TABLE1 enable constraint TEST_UNIQUE_CONSTRAINT1;
The issue is that i have multiple schemas (say: TESTSCHEMA_1 to _5), and they all have tables with the same name TEST_TABLE1 which also have a Unique constraint with the same name TEST_UNIQUE_CONSTRAINT1.
As a result I get this error:
ORA-02299: cannot validate (TESTSCHEMA_1.TEST_UNIQUE_CONSTRAINT1) - duplicate keys found
How can I indicate specifically the schema where is the constraint i want to enable? I've tried using TESTSCHEMA_1.TEST_UNIQUE_CONSTRAINT1, but it throws a syntax error (Non-properly ended sql command)
check uniqueness of your data.
select unique_column_in_test_table1, count(unique_column_in_test_table1) from TESTSCHEMA_1.TEST_TABLE1
group by unique_column_in_test_table1
having count(unique_column_in_test_table1) > 1
if any rows return by this query you have to handle/correct it to be unique.