• Hi %

    kll (1/20/2010)


    Just remember that using any kind of @@identity or scope_identity() will still require some RBAR on multi line inserts.

    It's possible to use bulk insert operations if table containing the new rows to be inserted contains any kind of a surrogate id (or another uniqueness).

    ---========================================================

    -- table definitions

    -----------------------------------------------------------

    -- destination table for new data to be inserted

    DECLARE @Destination TABLE (

    Id INT NOT NULL IDENTITY(1,1)

    PRIMARY KEY CLUSTERED

    ,SomeInt INT

    );

    -----------------------------------------------------------

    -- table containing all rows to be newly inserted into

    -- destination table

    -- IMPORTANT

    -- the table containing the new data to be inserted requires

    -- any kind of uniqueness (e.g. a surrogate id)

    DECLARE @NewData TABLE (

    SurrogateId INT NOT NULL

    PRIMARY KEY CLUSTERED

    ,SomeInt INT

    );

    ---========================================================

    -- create some sample data

    -----------------------------------------------------------

    -- insert existing data into destination table

    INSERT INTO @Destination

    SELECT -777

    UNION ALL SELECT -888;

    -----------------------------------------------------------

    -- new rows to be inserted into destination table

    INSERT INTO @NewData

    SELECT -1, 11

    UNION ALL SELECT -2, 22;

    ---========================================================

    -- bulk insert rows into destination table and catch new identities

    -----------------------------------------------------------

    -- variables to catch count of inserted rows and scope-identity

    DECLARE

    @LastIdentity INT

    ,@RowCount INT;

    -----------------------------------------------------------

    -- bulk insert new rows into destination table

    -- IMPORTANT

    -- to get the following operations work ensure to use an

    -- ORDER BY in SELECT. To avoid problems due to paralellism

    -- use MAXDOP 1 option what should be okay for an INSERT

    INSERT INTO @Destination

    SELECT SomeInt

    FROM @NewData

    ORDER BY SurrogateId

    OPTION (MAXDOP 1);

    -----------------------------------------------------------

    -- catch the last created scope-identity and the count of

    -- rows inserted

    SELECT

    @LastIdentity = SCOPE_IDENTITY()

    ,@RowCount = COUNT(*)

    FROM @NewData;

    -----------------------------------------------------------

    -- use a CTE that creates a row number ordered by the

    -- surrogate id of newly inserted rows

    WITH cte AS (

    SELECT

    SurrogateId

    ,ROW_NUMBER() OVER (ORDER BY SurrogateId) RowNum

    FROM @NewData

    )

    SELECT

    *

    -- calculate destination table IDENTITY values

    ,@LastIdentity - @RowCount + RowNum

    FROM cte

    Greets

    Flo