SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
Search:  
 
 
        
Home       Members    Calendar    Who's On


««1234»»»

Composite primary key & auto increment problem Expand / Collapse
Author
Message
Posted Sunday, July 05, 2009 1:28 PM
Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: Today @ 8:24 AM
Points: 1,270, Visits: 1,505
paulneyman (7/5/2009)
Ok, can you write a sample how to do that?

No... we're not here to do your work for you. We will, however, guide you to find the solution.
As several have noted, your db design is flawed and needs to be redesigned.
If you insist on using a trigger, you've already been told what needs to be done inside it. (Except that you will also need to remove the identity function from the column.)
I would start by reading Books Online (BOL), the SQL Server Help System. You can access it by pressing the {F1} function key while in SQL Server Management Studio (SSMS). Look for "CREATE TRIGGER".


Wayne
For better assistance in answering your questions, click here
For performance problems, please read this.
Post #747401
Posted Sunday, July 05, 2009 2:00 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 8:56 AM
Points: 9,731, Visits: 9,587
WayneS (7/5/2009)
paulneyman (7/5/2009)
Ok, can you write a sample how to do that?

No... we're not here to do your work for you. We will, however, guide you to find the solution.
As several have noted, your db design is flawed and needs to be redesigned.
If you insist on using a trigger, you've already been told what needs to be done inside it. (Except that you will also need to remove the identity function from the column.)
I would start by reading Books Online (BOL), the SQL Server Help System. You can access it by pressing the {F1} function key while in SQL Server Management Studio (SSMS). Look for "CREATE TRIGGER".
I concur, your db design is flawed, and fails the 3NF.

The data is obviously not dependent on the key, the whole, and nothing but the key, so help you Codd.

You should be able to redesign the underlying db structure and hide that enhanced structure behind stored procedures/views if necessary.




Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Post #747407
Posted Monday, July 06, 2009 1:34 AM
Grasshopper

GrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopper

Group: General Forum Members
Last Login: Tuesday, August 04, 2009 1:52 PM
Points: 11, Visits: 28
So there is a solution based on trigger INSTEAD OF INSERT:

DROP TABLE Product
GO

CREATE TABLE Product
(
[ProductID] int,
[CategoryID] int,
[Name] varchar(MAX) NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[CategoryID] ASC,
[ProductID] ASC
)
)
GO

CREATE TRIGGER InsteadTrigger on Product
INSTEAD OF INSERT
AS
BEGIN

BEGIN TRANSACTION

DECLARE @PK INT

SELECT @PK = ISNULL(MAX([ProductID]),0) + 1
FROM Product
WHERE [CategoryID] = (SELECT [CategoryID] FROM inserted)

INSERT INTO Product ([ProductID],[CategoryID],[Name])
SELECT @PK,[CategoryID],[Name]
FROM inserted

COMMIT TRANSACTION

END
GO

INSERT INTO Product([CategoryID],[Name])
VALUES(1,'Prod 1 for Cat 1')
INSERT INTO Product([CategoryID],[Name])
VALUES(1,'Prod 2 for Cat 1')

INSERT INTO Product([CategoryID],[Name])
VALUES(2,'Prod 1 for Cat 2')
INSERT INTO Product([CategoryID],[Name])
VALUES(2,'Prod 2 for Cat 2')

SELECT * FROM Product

Is it ok? It works , but is it good enought?
Post #747537
Posted Monday, July 06, 2009 1:48 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Yesterday @ 9:28 AM
Points: 14,526, Visits: 10,415
There's a chance that will cause duplicate key errors under heavy load. Two queries run at the same time, both do the SELECT MAX and get the same value (shared locks are shared), both try to insert the same value into the table and one fails with a duplicate key error (or maybe even a deadlock)

To fix that, your select max needs a more restrictive lock. Updlock is the one usually used. That however is going to hurt concurrency.

There's no real good way of doing this. Either you risk occasional failures or you risk contention and blocking at higher volumes.



Gail Shaw

We walk in the dark places no others will enter
We stand on the bridge and none may pass

Post #747541
Posted Monday, July 06, 2009 1:50 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Yesterday @ 9:28 AM
Points: 14,526, Visits: 10,415
Lynn Pettis (7/5/2009)
I concur, your db design is flawed, and fails the 3NF.


It's violating BCNF if I'm not mistaken. There's no inter-data dependency (so passed 3NF) but there is a dependency between two of the columns in the key.



Gail Shaw

We walk in the dark places no others will enter
We stand on the bridge and none may pass

Post #747542
Posted Monday, July 06, 2009 2:09 AM
Grasshopper

GrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopperGrasshopper

Group: General Forum Members
Last Login: Tuesday, August 04, 2009 1:52 PM
Points: 11, Visits: 28
There's a chance that will cause duplicate key errors under heavy load


How can I improve my solution?
Post #747555
Posted Monday, July 06, 2009 2:15 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Yesterday @ 9:28 AM
Points: 14,526, Visits: 10,415
As I said...

To fix that, your select max needs a more restrictive lock. Updlock is the one usually used. That however is going to hurt concurrency.


Why are you insisting on this design? You're causing yourself a lot of extra work and potential future problems with this.



Gail Shaw

We walk in the dark places no others will enter
We stand on the bridge and none may pass

Post #747557
Posted Monday, July 06, 2009 7:01 AM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 8:56 AM
Points: 9,731, Visits: 9,587
GilaMonster (7/6/2009)
Lynn Pettis (7/5/2009)
I concur, your db design is flawed, and fails the 3NF.


It's violating BCNF if I'm not mistaken. There's no inter-data dependency (so passed 3NF) but there is a dependency between two of the columns in the key.


No, don't think so. For instance, Product specific information that is not related to Category is not dependent on the whole key, just the Product portion of the key. An example would be the Product Name or Description. Same with any information related only to Category such as Category Name or Description.

Based on a post in another thread I don't think this is even 2NF:

1NF - The Key
2NF - The Whole Key -- Shouldn't Product and Category be split at this point?
3NF - Nothing but The Key




Lynn Pettis

For better assistance in answering your questions, click here
For tips to get better help with Performance Problems, click here
For Running Totals and its variations, click here or when working with partitioned tables
For more about Tally Tables, click here
For more about Cross Tabs and Pivots, click here and here
Managing Transaction Logs

SQL Musings from the Desert Fountain Valley SQL (My Mirror Blog)
Post #747674
Posted Monday, July 06, 2009 7:19 AM


SSChampion

SSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampionSSChampion

Group: General Forum Members
Last Login: Yesterday @ 9:28 AM
Points: 14,526, Visits: 10,415
Lynn Pettis (7/6/2009)
2NF - The Whole Key -- Shouldn't Product and Category be split at this point?


Could be, but we don't know if Name (the only non-key attribute that we've been shown) is dependent on part or all of the key. It's a potential 2NF violation. If not then it's definitely a BCNF violation.



Gail Shaw

We walk in the dark places no others will enter
We stand on the bridge and none may pass

Post #747698
Posted Monday, July 06, 2009 11:06 AM
SSCertifiable

SSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiable

Group: General Forum Members
Last Login: Today @ 8:50 AM
Points: 7,646, Visits: 4,162
There is one way to solve this without using a trigger and without hurting performance, while still keeping the data in the format you want. What you would need to do is create one table for each category, with an identity column in each table, and use a partitioned view on top of them.

Of course, that opens up the door for all kinds of structure management issues, but it does comply with the constraints given thus far.

Have to say, though, that I'd never do it.

I'd have a ProductID that was a simple identity column, and have category as one of the data columns, with an FK to a Categories table. CategoryID wouldn't be part of the PK, and ProductID wouldn't depend on CategoryID.

That would be well normalized, would scale well, be easy to work with, and would fulfil all the real-world requirements that any normal business has on this kind of thing.


- GSquared

"Nobody knows the age of the human race, but everyone agrees it's old enough to know better." - Anon
Post #747897
« Prev Topic | Next Topic »

««1234»»»

Permissions Expand / Collapse