2008-11-27 24 views
7

Esto me parece ser el tipo de problema que surgiría todo el tiempo con el desarrollo de SQL/base de datos, pero luego soy nuevo en todo esto, así que perdona mi ignorancia.Insertar SQL en tablas relacionadas

Tengo 2 tablas:

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 

y

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] 

quiero insertar una nueva entrada en la tabla de pistas. Esto también implicará insertar una nueva entrada en la tabla trackstrings y asegurarse de que la columna de clave foránea tracktringid en pistas apunta a la nueva entrada en trackssings. ¿Cuál es el medio más eficiente para lograr esto?

Respuesta

10

Primero, inserte en TrackStrings, omitiendo la columna de la clave principal de la lista de columnas. Esto invoca su columna IDENTITY que genera un valor automáticamente.

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

En segundo lugar, insertar en Tracks y especifique como su TrackStringId la función SCOPE_IDENTITY(), que devuelve el valor más reciente generada por una columna de IDENTITYen su ámbito actual.

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

Primero inserte en la tabla principal.

INSERT INTO trackstrings VALUES('myvalue') 

Siguiente obtener la identidad. Este método depende de si lo está haciendo todo en una declaración o en un procedimiento almacenado u otro método. Asumiré 1 enunciado así que solo insertaré con la variable especial de identidad.

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

Algo así debería hacerlo dependiendo de su situación concreta. La clave es la variable @@ IDENTITY. Tiene el último valor de identidad insertado para la conexión que está utilizando. No es específico de la tabla, es simplemente la identidad más reciente insertada durante la vida útil de las conexiones.

+4

@@ IDENTIDAD no es la mejor manera de hacerlo. SCOPE_IDENTITY() es mucho más seguro. Si hay un desencadenador que funciona un poco cuando se inserta en cadenas de pistas y se inserta en una tabla con una identidad, obtendrá la identidad del desencadenante y no de la tabla original. –

+1

Genial, gracias por la información. No me di cuenta de la diferencia. – palehorse

+0

Lea esto para saber por qué @@ Identity no debe utilizarse en este caso: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve- last-inserted-identity-of-record / – hidden

5

Si está utilizando SQL Server 2005 o posterior y está insertando una gran cantidad de registros en un solo INSERT, se puede mirar en OUTPUT o OUTPUT INTO opciones here utilizar las identidades de la primera inserción en el segundo sin haveing ​​a "re -indica "las filas para obtener todos los valores IDENTITY.

Cuestiones relacionadas