views:

1330

answers:

3

This seems to me to be the kind of issue that would crop up all the time with SQL/database development, but then I'm new to all this, so forgive my ignorance.

I have 2 tables:

CREATE TABLE [dbo].[Tracks](
    [TrackStringId] [bigint] NOT NULL,
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Time] [datetime] NOT NULL,
 CONSTRAINT [PK_Tracks] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
        IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
        ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Tracks] CHECK CONSTRAINT [FK_Tracks_AudioStreams]
GO

ALTER TABLE [dbo].[Tracks]  WITH CHECK ADD  CONSTRAINT
[FK_Tracks_TrackStrings]     FOREIGN KEY([TrackStringId])
REFERENCES [dbo].[TrackStrings] ([Id])
GO

ALTER TABLE [dbo].[Tracks] CHECK CONSTRAINT [FK_Tracks_TrackStrings]
GO

and

CREATE TABLE [dbo].[TrackStrings](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [String] [nvarchar](512) NOT NULL,
 CONSTRAINT [PK_Strings] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
        IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
        ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

I want to insert a new entry into the tracks table. This will also involve inserting a new entry in the trackstrings table, and ensuring that the foreign key column trackstringid in tracks points to the new entry in trackstrings. What is the most efficient means of achieving this?

+2  A: 

First, insert into TrackStrings, omitting the primary key column from the column list. This invokes its IDENTITY column which generates a value automatically.

INSERT INTO [dbo].[TrackStrings] ([String]) 
  VALUES ('some string');

Second, insert into Tracks and specify as its TrackStringId the function SCOPE_IDENTITY(), which returns the most recent value generated by an IDENTITY column in your current scope.

INSERT INTO [dbo].[Tracks] ([TrackStringId], [Time]) 
  VALUES (SCOPE_IDENTITY(), CURRENT_TIMESTAMP());
Bill Karwin
A: 

First insert into the primary table.

INSERT INTO trackstrings VALUES('myvalue')

Next get the identity. This method depends on whether you're are doing it all in 1 statement or a stored procedure or some other method. I will assume 1 statement so I'll just insert with the identity special variable.

INSERT INTO tracks VALUES( @@IDENTITY, getdate() )

Something like that should do it depending on your exact scenario. The key is the @@IDENTITY variable. It holds the last inserted identity value for the connection you are using. It is not table specific, it is simply the most recent identity inserted during the connections lifespan.

palehorse
@@IDENTITY is not the best way to do this. SCOPE_IDENTITY() is much safer. If there is a trigger that does some work when inserting into trackstrings and it inserts into a table with an identity, you will get the identity from the trigger and not the original table.
Micky McQuade
Cool, thank you for the info. I did not realize the difference.
palehorse
+1  A: 

If you are using SQL Server 2005 or later and are inserting a lot of records in a single INSERT, you can look into OUTPUT or OUTPUT INTO options here to use the identities from the first insert in the second without haveing to "re-find" the rows to get all the IDENTITY values.

Cade Roux