views:

404

answers:

3

I have a table called table1 which has a composite primary key using 'ScreenId' and 'ActivityItemId'. I have added a new field 'ProductId' which has a NOT NULL constraint. I want to add ProductId to the composite primary key.

I thought that this would work

db.execute "ALTER TABLE table1 PRIMARY KEY (ScreenId, ActivityItemId, ProductId)"

but i get an error, i think this syntax only works when creating a table.

Can anyone help me out with the SQL? (i can't use a visual basic solution here btw, i'm actually using a ruby interface in order to run the sql, so it needs to be just in SQL)

thanks max

+4  A: 

Try to drop your current primary key and then create new one:

ALTER TABLE table1 DROP CONSTRAINT pk_name

ALTER TABLE table1 ADD CONSTRAINT pk_name PRIMARY KEY (ScreenId, ActivityItemId, ProductId)

Sergey Olontsev
Thanks Hawx - but i get this error OLE error code:80004005 in Microsoft JET Database Engine CHECK constraint 'Primary Key' does not exist.I was running this - maybe this isn't the right syntax?"ALTER TABLE table1 DROP CONSTRAINT [PrimaryKey]"
Max Williams
Instead of [Primary Key] use your primary key name.
Sergey Olontsev
ah i see, square brackets as in 'insert your variable here'.\nStill no luck i'm afraid - i'm executing this:ALTER TABLE Activity DROP CONSTRAINT ScreenIdand i get this error backCHECK constraint 'ScreenId' does not exist.ScreenId is definitely one of the primary key fields in this table though. This is an access DB - is there a different syntax required for access maybe?thanks a lot - max
Max Williams
That's axactly Access syntax, taken from Access online help. The problem is, that the name of primary key constraint is wrong. Also, try this one "ALTER TABLE Activity DROP CONSTRAINT PrimaryKey;" I hope, it will drop the primary key without knowing its name.
Sergey Olontsev
Managed to drop the primary key - the actual composite key name was 'Key1' and it was that that i had to pass to the 'DROP CONSTRAINT' clause.The adding a new primary key bit worked first time. Thanks a lot for all your help guys! max
Max Williams
+3  A: 

Think about a surrogate key instead of a composite key. You don't want to have to change your schema every time your business logic changes.

It might be worth it to keep those relationships as unique constraints and add a surrogate key.

duffymo
+1: "Composite Primary Key" that changes isn't actually primary. It changed, so it's not the "one and only identifier for the row. Make the composite key an ordinary index and add a unique surrogate key.
S.Lott
Thanks Duffymo. This isn't really my business logic, we wouldn't use access for our business :) It's really just a one-off job.<br/>Having said that i'm not averse to using a surrogate key to solve the problem, i've not heard the term before though. I'll look it up.
Max Williams
Very good, Max. If you're using Access, add a column named id that's type AutoNumber and you're fine. Use a unique constraint for the other columns.
duffymo
-1 "You don't want to have to change your schema every time your business logic changes" -- you may not want to but changing the schema is inevitable when you business logic changes. Also, natural key vs surrogate is a religious matter.
onedaywhen
I've seen databases that uses Social Security Number as the primary key for a user because it was "natural" that had to scramble when privacy laws made it difficult to get. Nothing religious about that.
duffymo
@duffymo: agreed, choosing the wrong natural key is not a religious matter. However, suggesting a surrogate key without knowing (more like not caring) about the individual circumstances is a religious matter.
onedaywhen
You have no idea whether or not I care. You're remiss in assuming so.
duffymo
A: 

Have you tried to change the primary key with the design view instead of using SQL?

Walter Mitty
-1 they said, "i'm actually using a ruby interface in order to run the sql, so it needs to be just in SQL".
onedaywhen
OOPs! My bad. I would still be curious as to what gyrations the design view interface makes you go through to accomplish this task. Max got the solution he was looking for as soon as he learned how to name the constraint he was trying to drop. All's well that ends well.
Walter Mitty
One thing about using the interface I'm not sure about is how to specify the oder of the columns in the PK i.e. ScreenId then ActivityItemId then ProductId in that order. This is very important when you consider that the Access database engine uses the PK to physically cluster data on disk. What if the UI always adds the new column after all the others? How to find out if it did or not? Because of the unknowns it is safer for me to use SQL DDL.
onedaywhen