I have a SQL Server table:
+----+-------------+-------------------+
| ID | CompanyID | CompanyCode |
+----+-------------+-------------------+
| 1 | 1 | AAAA-123 |
| 2 | 2 | BBBB-111 |
| 3 | 1 | AAAA-123 |
| 4 | 3 | CCCC-999 |
| 5 | 3 | CCCC-999 |
| 6 | 1 | AAAA-123 |
+----+-------------+-------------------+
The ID field is the PK.
The CompanyID and CompanyCode fields specify a unique company whereby a CompanyID will ALWAYS have the same CompanyCode (and vice versa) and no two Companies will ever have the same CompanyID and/or CompanyCode.
I would like to create a rule on the table that will never allow a record to be added to the table if/when a CompanyCode doesn’t match an existing CompanyCode where the CompanyID‘s match.
The following is an example of what I cannot allow to occur on the table:
+----+-------------+-------------------+
| ID | CompanyID | CompanyCode |
+----+-------------+-------------------+
| 1 | 1 | AAAA-123 |
| 2 | 1 | BBBB-111 |<<<< This record should not be allowed
| 3 | 1 | AAAA-123 |
| 4 | 3 | CCCC-999 |
| 5 | 3 | CCCC-999 |
| 6 | 1 | AAAA-123 |
+----+-------------+-------------------+
Notice the record with ID=2, the CompanyCode BBBB-111 doesn’t match the existing record that has a CompanyCode of AAAA-123.
I want this rule to exist on the table somehow – i.e. I don’t want this rule to be a business rule that queries and/or stored procedures have to manage.
I suppose you can say I’m wanting to enforce duplicate records (on CompanyID and CompanyCode) if and only if an existing CompanyID and/or CompanyCode exists in the table.
Is this possible to do at the table design level? Or am I stuck with having to manage this in my scripts?
Update
Although this isn’t really pertinent to my OP, from the feedback I received, I suppose I should give a little background on the CompanyID/CompanyCode table design.
First off, this is just a mock table design to try to explain my question – my real table has nothing to do with companies.
Second, my real table is a middle-man between two web-services where Service1 creates a DeviceID and Service2 collects a SerialNumber that exists in a micro-device. Also, my real table contains many other columns that this middle-man server has to process.
One of the strange things about this middle-man service is that the table that I’m talking about has to allow NULLS for both the DeviceID and SerialNumber – it all depends on which Service sent a record first…. I’m am talking too much and going way off topic of my original question, but I thought I had to clarify my table example since I was getting much flak in regards to my breaking normalization.
Okay, this isn’t the prettiest of code, but it does enforce the constraint, I think. The trick is to create an indexed view with two unique indexes defined on it:
Now we insert some initial data:
We can add another row with exactly the same values for
Col1andCol2:But if we pick a value for
Col2that has been used for anotherCol1, or vice versa, we get errors:The trick here was to observe that this query:
will only have one row for a particular
Col1value, and only one row with a particularCol2value, provided that the constraint you’re seeking to enforce has not been broken – but as soon as a non-matching row is inserted into the base table, this query returns multiple rows.