Here is the problem du jour: You
must rebuild a table (T1), and make sure you preserve the primary key (PK) values in T1.
You want to move all the data into table T2, which has an identity key, while
preserving the PKs from table T1. Once you move all
the T1 data into T2, you want T2’s identity key to work as expected. That is,
suppose the highest key you insert is 12345, then once
you’re finished, the next insert should be keyed 12346.
Just to add a wrinkle to the problem—one borrowed from an
app I am currently working on—we not only have two tables but we also have two
separate applications: one designed for accounting purposes and the other
designed for much more detailed management of the projects involved.
The accounting database was built after the fact. The ProjectIDs in this table are integers but not identity keys. In the prior application, ProjectID is an identity key. Fortunately, the developer defined the PK as Identity( 10000, 1 )—after examining the keys in the accounting app and determining that this seed was guaranteed to create no conflicts.
How do you force T1’s data into T2?
Assuming that all your other ducks are in a row (column
types and counts match), now you have to figure out how to force T1’s data into T2. The code in
Listing A creates a
test table with an identity key, inserts a couple of rows while allowing SQL to
determine the identity key, forces a new row in with a specific key, and
finally inserts a fourth row allowing SQL to generate its key. (Before running
this code, choose a test database.)
So far, so good. We have
demonstrated how to forcibly insert a given PK into a table. You typically need
to do this when importing identity keys from one table into another. However, there is a problem. Run the code in
Listing B.
It turns out that this bizarre behavior was allowed due to
the sloppy coding in the table-creation statement. We should have written the
following:
CREATE TABLE T1 ( PKint IDENTITY PRIMARY KEY, SomeTextvarchar(100))
This code changes the behavior to what you would naturally
expect. When you run the line that attempts to insert a duplicate PK, you get
the following error message:
Server: Msg 2627, Level 14, State 1, Line 1
Violation of PRIMARY KEY constraint 'PK__T1__7F60ED59'. Cannot insert duplicate
key in object 'T1'.
The statement has been terminated.
Summing up what you’ve learned
While this problem isn’t common in an intelligently designed
database, it does arise in the other 90 percent of databases. Therefore,
remember the following lessons:
- You
can force specific entries into any identity key column. - You
must ensure that said column has explicitly been defined as a PK column;
otherwise, you’re inviting disaster. - After
forcing the explicit entries you need, make sure that you SET Identity_Insert OFF.
TechRepublic’s free SQL Server newsletter, delivered each Tuesday, contains hands-on tips that will help you become more adept with this powerful relational database management system. Automatically subscribe today!