Question

I have two tables, the first has a primary key that is an identity, the second has a primary key that is not, but that key has a foreign key constraint back to the first table's primary key.

If I am inserting one record at a time I can use the Scope_Identity to get the value for the pk just inserted in table 1 that I want to insert into the second table.

My problem is I have many records coming from selects I want to insert in both tables, I've not been able to think of a set based way to do these inserts.

My current solution is to use a cursor, insert in the first table, get key using scope_identity, insert into second table, repeat.

Am I missing a non-cursor solution?

Was it helpful?

Solution

Yes, Look up the output clause in Books online.

OTHER TIPS

I had this problem just this week: someone had introduced a table with a meaningless surrogate key into the schema where naturally keys are used. No doubt I'll fix this soon :) until then, I'm working around it by creating a table of data to INSERT from: this could be a permanent or temporary base table or a derived table (see below), which should suit your desire for a set-based solution anyhow. Use a join between this table and the table with the IDENTITY column on the natural key to find out the auto-generated values. Here's a brief example:

CREATE TABLE Test1 
(
 surrogate_key INTEGER IDENTITY NOT NULL UNIQUE, 
 natural_key CHAR(10) NOT NULL CHECK (natural_key NOT LIKE '%[^0-9]%') UNIQUE
);

CREATE TABLE Test2
(
 surrogate_key INTEGER NOT NULL UNIQUE
    REFERENCES Test1 (surrogate_key), 
 data_col INTEGER NOT NULL
);

INSERT INTO Test1 (natural_key)
SELECT DT1.natural_key
  FROM (
        SELECT '0000000001', 22
        UNION ALL 
        SELECT '0000000002', 55
        UNION ALL 
        SELECT '0000000003', 99
       ) AS DT1 (natural_key, data_col);

INSERT INTO Test2 (surrogate_key, data_col)
SELECT T1.surrogate_key, DT1.natural_key
  FROM (
        SELECT '0000000001', 22
        UNION ALL 
        SELECT '0000000002', 55
        UNION ALL 
        SELECT '0000000003', 99
       ) AS DT1 (natural_key, data_col)
       INNER JOIN Test1 AS T1
          ON T1.natural_key = DT1.natural_key;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top