2008-11-27 9 views
7

Cela me semble être le genre de problème qui surgirait tout le temps avec le développement SQL/base de données, mais alors je suis nouveau à tout cela, alors pardonnez mon ignorance.Insertion SQL dans des tables connexes

J'ai 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 

et

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] 

Je veux insérer une nouvelle entrée dans la table des pistes. Cela impliquera également d'insérer une nouvelle entrée dans la table trackstrings, et de s'assurer que la piste keystringid de la clé étrangère dans les pistes pointe vers la nouvelle entrée dans trackstrings. Quel est le moyen le plus efficace pour y parvenir?

Répondre

10

D'abord, insérez dans TrackStrings en omettant la colonne de clé primaire de la liste de colonnes. Ceci appelle sa colonne IDENTITY qui génère automatiquement une valeur.

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

En second lieu, insérer dans Tracks et spécifiez comme TrackStringId la fonction SCOPE_IDENTITY(), qui renvoie la valeur la plus récente générée par une colonne IDENTITYdans votre périmètre actuel.

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

Première insertion dans la table primaire.

INSERT INTO trackstrings VALUES('myvalue') 

Ensuite, obtenez l'identité. Cette méthode dépend si vous le faites tous dans une instruction ou une procédure stockée ou une autre méthode. Je vais supposer 1 déclaration donc je vais juste insérer avec la variable d'identité spéciale.

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

Quelque chose comme ça devrait le faire en fonction de votre scénario exact. La clé est la variable @@ IDENTITY. Il contient la dernière valeur d'identité insérée pour la connexion que vous utilisez. Ce n'est pas spécifique à une table, c'est simplement l'identité la plus récente insérée pendant la durée de vie des connexions.

+4

@@ IDENTITY n'est pas le meilleur moyen de le faire. SCOPE_IDENTITY() est beaucoup plus sûr. S'il y a un déclencheur qui fonctionne un peu lors de l'insertion dans trackstrings et qu'il s'insère dans une table avec une identité, vous obtiendrez l'identité du trigger et non la table d'origine. –

+1

Cool, merci pour l'info. Je n'ai pas réalisé la différence. – palehorse

+0

Veuillez lire ceci pour savoir pourquoi @@ Identity ne doit pas être utilisé dans ce cas: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve- dernière-insérée-identité-d'enregistrement / – hidden

5

Si vous utilisez SQL Server 2005 ou version ultérieure et insérez beaucoup de disques dans un seul INSERT, vous pouvez regarder dans OUTPUT ou OUTPUT INTO les options here d'utiliser l'identité de la première insertion dans la seconde sans haveing ​​à « re -find "les lignes pour obtenir toutes les valeurs IDENTITY.

Questions connexes