PostgreSQL - Add CONSTRAINT UNIQUE and do not validate exisiting data - sql

I have a small problem with adding new CONSTRAINT to my table.
I want to add a UNIQUE CONSTRAINT and do not validate existing data in my table.
I have some duplicates in existing data and I want to leave it like it is.
I wrote a query:
ALTER TABLE tbl1
ADD CONSTRAINT unique_const UNIQUE (fld1, fld2) NOT VALID;
But it's not working, I got an error:
UNIQUE constraints cannot be marked NOT VALID
I also tried removing all TRIGGERS:
ALTER TABLE tbl1 DISABLE TRIGGER all;
ALTER TABLE tbl1 ADD CONSTRAINT unique_const UNIQUE (fld1, fld2);
ALTER TABLE tbl1 ENABLE TRIGGER all;
But it also does not work.
Does anyone know how to add a UNIQUE CONSTRAINT without validating existing rows?

According to the documentation of PostgreSQL 9.6, unfortunately the NOT VALID option is currently only allowed with foreign key and CHECK constraints.
This StackOverflow thread here might be related and provide ideas/basic approaches for an alternative solution, although it's from 2014.

If you can specifically identify those lines which should be ignored for the constraint, you could add a partial unique index:
CREATE UNIQUE INDEX ON table (columns) WHERE some_condition;
If you don't have an existing direct condition, you may need to add a column to the table to identify those lines that should be ignored (with an appropriate default so that new lines are counted).
Not sure if there's an equivalent ALTER TABLE syntax.

Related

Query to Alter Primary Key to any column with keyword

I have a database with several tables that I am looking to add primary keys to any column with the keyword "KEY" in its name. The first problem that doesn't seem fixable is to run a query against all tables rather than one by one... Secondly I don't see how I can Add Primary key or even drop constraints on wildcard column searches.
For those of you who are visual, this is what I am trying to achieve:
ALTER TABLE *
ADD PRIMARY KEY (%KEY%);
Keeping in mind SOME tables already have Primary Keys attached, so I may need to Drop Constraints on all first then re-constrain them. If even possible?
If you want to define existing autonumber fields as primary key, consider:
ALTER TABLE tablename ADD CONSTRAINT fieldname PRIMARY KEY(fieldname)
However, field cannot already be set with an index and table cannot already have a primary key. Again, use ALTER TABLE to remove index.
ALTER TABLE tablename DROP CONSTRAINT indexname
Will have to run this SQL for each table that must be modified. If this is a one-time only requirement (why would it not be?), probably just as fast to open each table and manually modify design.
MS documentation https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/alter-table-statement-microsoft-access-sql
The alternative is VBA using TableDefs to modify table structure. Search web for examples.

Create autoserial column in informix

is it possible to create a autoserial index in order 1,2,3,4... in Informix and what would be the syntax. I have a query and some of my timestamps are identical so I was unable to query using a timestamp variable. Thanks!
These are the commands that I ran to add an id field to an existing table. While logged in to the dbaccess console.
alter table my_table add id integer before some_field;
create sequence myseq;
update my_table set id = myseq.nextval;
drop sequence myseq;
alter table my_table modify (id serial not null);
Thanks to #ricardo-henriques for pointing me in the right direction. These commands will allow you to run the instructions explained in his answer on your database.
That would be the SERIAL data type.
You can use, as #RET mention the SERIAL data type.
Next you will struggle with the fact that you can't add a SERIAL column to an existing table. Ways to work around:
Add an INTEGER column, populate with sequential numbers and then alter the column to SERIAL.
Unload the data to a file, drop the table and recreate it with the new column.
Create a new table with the new column, populate the new table with the data from the old, drop the old and rename the new.
...
Bear in mind that they may not be unique. Hence you have to create an unique index or a primary key or an unique constraint in the column to prevent duplicates.
Another notes you should be aware:
- Primary key don't allow NULLS, unique index and unique constraints allow (as long there is only one record), so you should specify NOT NULL on the column definition.
- If you use a primary key or a unique constraint you can create a foreign key to it.
- In primary key and unique constraint the validation of the uniqueness of the record is done in the end of the DML, for the unique index it is done row a row.
Seems you're getting your first touch with informix, welcome. Yes it can be a little bit hard on the beginning just remember:
Always search before asking, really search.
When in doubt or reached a dead end then ask away.
Try to trim down your case scenario, built your own case the simple away you can, these will not only help us to help us but you will practice and in some cases find the solution by yourself.
When error is involve always give the error code, in informix it is given at least one error code and sometimes an ISAM error too.
Keen regards.

Primary Key and Unique Index -- sql scripts generated by SQL Developer

When export sql scripts by SQL Developer there are multiple options available, but either way there have to generate a UNIQUE INDEX on primary key like this
CREATE UNIQUE INDEX "SYS_C0018099" ON "TRANSACTION" ("ID")
and add PRIMARY KEY to the same table and same column
ALTER TABLE "TRANSACTION" ADD PRIMARY KEY ("ID")
So the question is: does it looks like kind of redundancy? I thought creating a primary key on a column should by default create an unique index on that column too? So why the first command is necessary?
And this may cause data redundancy?
I am on Oracle 11g so please share any ideas about why it should look like above.
Thanks in advance.
There is no redundancy - or only a little bit :)
The second command will use the index available if exists. Otherwise(if first DDL does not exists) will create an index.
The split into two commands is useful when you had given a proper name to the index and want to keep it.
UPDATE: The link indicated by Thomas Haratyk is a must read, I really like it: http://viralpatel.net/blogs/understanding-primary-keypk-constraint-in-oracle/
UPDATE2: a_horse_with_no_name is right, it can be done in a single statement like:
alter table TRANSACTION
add CONSTRAINT pk_test PRIMARY KEY (id);
So, it will keep the name(won't create a sysblalbla object name) and if you use the 'USING INDEX' keyword you can specify index atributes, for example storage atributes.
But again, you will not have any problems with those two statements, only an index is created.
Probably SQL Developer prefer to get a ddl per object and there might be cases when it's better its way.

SQL Server CHECK Constraint - Ensure no duplicates on text

Need to add some sort of constraint on my table column. I need to make sure that the user does not enter, manually or otherwise, the same text in more than one row of the table. How can I achieve this?
You'll want to use some type of unique constraint or, of course, the primary key would work as well. For example:
ALTER TABLE MyTable ADD CONSTRAINT UK_MyUniqueConstraint UNIQUE (MyColumn)
There are other methods of creating this discussed on SE as well.

Alter composite key to include newly added column in sql server 2005

I have a table GB_Assignor_Assignee. I have a primary key which includes this combination(StateCode, CountyID, Doc_Type_Group_Code). Now i have to add a new column Doc_Type_Code. I added it by altering table. I want to include this new column inside this primary key.So my combination will be(StateCode, CountyID, Doc_Type_Group_Code,Doc_Type_Code).
How can i alter this primary key to add new column. I donot want to drop it and then recreate it. Please suggest.
If you want to change the primary key to include a new column, you have to drop and recreate it - there's no other way. You cannot add a column to an existing primary key after it's been created.
The question is: wouldn't you be better off creating a new artificial ID (of type INT) as your PK? You wouldn't have to change it if yet another column comes along, referencing the table will be MUCH easier (JOIN on just a single INT instead of five or six columns)......
You have to drop and recreate your PK.
This involves dropping any foreign keys that reference it. This should be obvious in any case as the foreign keys would also have to change to reflect the new column. (Hopefully not many in the case of composite PKs).
Drop the PK itself.
Create the new PK with the additional column.
Recreate all foreign keys.
The easiest way to do this is to make the change in SQL Server's table designer, and ask it to generate the change script for you.