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.
Related
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.
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.
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.
I'm working with a legacy SQL Server database which has a core table with a bad primary key.
The key is of type NVARCHAR(50) and contains an application-generated string based on various things in the table. For obvious reasons, I'd like to replace this key with an auto-incrementing (identity) INT column.
This is a huge database and we're upgrading it piece-by-piece. We want to minimize the changes to tables that other components write to. I figured I could change the table without breaking anything by just:
Adding the new Id column to the table and making it nullable
Filling it with unique integers and making it NOT NULL
Dropping the existing primary key while ensuring there's a uniqueness constraint still on that column
Setting the new Id column to be the new primary key and identity
Item 3 is proving very painful. Because this is a core table, there are a lot of other tables with foreign key constraints on it. To drop the existing primary key, it seems I have to delete all these foreign key constraints and create them again afterwards.
Is there an easier way to do this or will I just have to script everything?
Afraid that is the bad news. We just got through a big project of doing the same type of thing, although our head DBA had a few tricks up his sleeve. You might look at something like this to get your scripts generated for the flipping of the switch:
I once did the same thing and basically used the process you describe. Except of course you have to first visit each other table and add new foreign key pointing to the new column in your base table
So the approach I used was
Add a new column with an auto incrementing integer in the base table, ensure it has a unique index on it (to be replaced later by the primary key)
For each foreign key relationship pointing to the base table add a new column in the child table. (note this can result in adding more than one column in the child table if more than one relationship)
For each instance of a key in the child table enter a value into the new foreign key field(s)
Replace your foreign key relationships such that the new column now serves
Make the new column in the base table the primary
Drop the old primary key in the base table and each old foreign key in the
children.
It is doable and not as hard as it might sound at first. The crux is a series of update statements for the children table of the nature
Update child_table
set new_column = (select new_primary from base)
where old_primary = old_foreign
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.