2008-11-27 20 views
7

Questo mi sembra il tipo di problema che si svilupperebbe continuamente con lo sviluppo di SQL/database, ma poi sono nuovo a tutto questo, quindi perdona la mia ignoranza.Inserimento SQL in tabelle correlate

Ho 2 tabelle:

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 

e

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] 

voglio inserire una nuova voce nella tabella tracce. Ciò comporterà anche l'inserimento di una nuova voce nella tabella trackstrings e assicurando che la colonna chiave esterna trackstringid nelle tracce punti alla nuova voce in trackstrings. Qual è il mezzo più efficace per raggiungere questo obiettivo?

risposta

10

Innanzitutto, inserire TrackStrings, omettendo la colonna chiave primaria dall'elenco di colonne. Questo richiama la sua colonna IDENTITY che genera automaticamente un valore.

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

In secondo luogo, inserire nella Tracks e specificare come la sua TrackStringId la funzione SCOPE_IDENTITY(), che restituisce il valore più recente generato da un IDENTITY colonna nel dell'ambito corrente.

INSERT INTO [dbo].[Tracks] ([TrackStringId], [Time]) 
    VALUES (SCOPE_IDENTITY(), CURRENT_TIMESTAMP()); 
0

Primo inserimento nella tabella principale.

INSERT INTO trackstrings VALUES('myvalue') 

Quindi ottenere l'identità. Questo metodo dipende dal fatto che tu stia eseguendo tutto in 1 istruzione o una stored procedure o qualche altro metodo. Assumerò 1 affermazione quindi inserirò solo con la variabile speciale di identità.

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

Qualcosa del genere dovrebbe farlo a seconda del vostro scenario esatto. La chiave è la variabile @@ IDENTITY. Contiene l'ultimo valore di identità inserito per la connessione che si sta utilizzando. Non è una tabella specifica, è semplicemente l'identità più recente inserita durante la durata delle connessioni.

+4

@@ IDENTITY non è il modo migliore per farlo. SCOPE_IDENTITY() è molto più sicuro. Se c'è un trigger che funziona quando si inserisce in trackstrings e si inserisce in una tabella con un'identità, si otterrà l'identità dal trigger e non dalla tabella originale. –

+1

Fantastico, grazie per le informazioni. Non ho capito la differenza. – palehorse

+0

Leggere per sapere perché @@ Identity non deve essere utilizzato in questo caso: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve- ultimo inserito identità di record / – hidden

5

Se si utilizza SQL Server 2005 o versione successiva e si inserisce un sacco di dischi in un unico INSERT, si può guardare in OUTPUT o OUTPUT INTO opzioni here di utilizzare le identità dal primo inserto nel secondo, senza haveing ​​a "ri -trovare "le righe per ottenere tutti i valori IDENTITY.