2010-08-11 35 views
7

bir sorgu ile şaşırıyorum.Uniqueidentifier ile eklenen son satırı, IDENTITY değil

ben veri türü Uniqueidentifier sütun ile bir sütun içeren bir tablo eklendi SON satır bulmak olduğunu gerekir: aspnet_Applications.ApplicationId Notlar: o Uniqueidentifier Bu sütun DEĞİL ve KİMLİK Sütun olduğunu.

ben eklenen son satırı alıp aspnet_Users.ApplicationId

MS SQL 2008'de SCOPE_IDENTITY kullanmaya çalıştı ama SCOPE_IDENTITY KİMLİK sütunla sadece çalışıyor çünkü çalışmıyor farklı bir masaya güncellemeniz de gerekir.

İşte kodum. Herhangi bir fikir?

CREATE DATABASE Test; 
GO 
USE Test; 
GO 

-- Create entities 
CREATE TABLE [dbo].[aspnet_Applications](
    [ApplicationName] [nvarchar](256) NOT NULL, 
    [LoweredApplicationName] [nvarchar](256) NOT NULL, 
    [ApplicationId] [uniqueidentifier] NOT NULL, 
    [Description] [nvarchar](256) NULL, 
PRIMARY KEY NONCLUSTERED 
(
    [ApplicationId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], 
UNIQUE NONCLUSTERED 
(
    [LoweredApplicationName] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], 
UNIQUE NONCLUSTERED 
(
    [ApplicationName] 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].[aspnet_Applications] ADD DEFAULT (newid()) FOR [ApplicationId] 
GO 


CREATE TABLE [dbo].[aspnet_Users](
    [ApplicationId] [uniqueidentifier] NOT NULL, 
    [UserId] [uniqueidentifier] NOT NULL, 
    [UserName] [nvarchar](256) NOT NULL, 
    [LoweredUserName] [nvarchar](256) NOT NULL, 
    [MobileAlias] [nvarchar](16) NULL, 
    [IsAnonymous] [bit] NOT NULL, 
    [LastActivityDate] [datetime] NOT NULL, 
PRIMARY KEY NONCLUSTERED 
(
    [UserId] 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].[aspnet_Users] WITH CHECK ADD FOREIGN KEY([ApplicationId]) 
REFERENCES [dbo].[aspnet_Applications] ([ApplicationId]) 
GO 

ALTER TABLE [dbo].[aspnet_Users] ADD DEFAULT (newid()) FOR [UserId] 
GO 

ALTER TABLE [dbo].[aspnet_Users] ADD DEFAULT (NULL) FOR [MobileAlias] 
GO 

ALTER TABLE [dbo].[aspnet_Users] ADD DEFAULT ((0)) FOR [IsAnonymous] 
GO 

-- Add data 
DECLARE @MyIdentity binary(16); 
INSERT INTO dbo.aspnet_Applications 
(
    ApplicationName, 
    LoweredApplicationName, 
    Description 
) 
VALUES 
(
    'x', 
    'x', 
    'Dummy text' 
); 
SET @MyIdentity = SCOPE_IDENTITY(); -- DOES NOT WORK 
PRINT @MyIdentity; -- DOES NOT WORK 

INSERT INTO dbo.aspnet_Users 
(
    ApplicationId, 
    UserName, 
    LoweredUserName, 
    MobileAlias, 
    IsAnonymous, 
    LastActivityDate 
) 
VALUES 
( 
    @MyIdentity, 
    'Administrator', 
    'administrator', 
    '', 
    0, 
    sysutcdatetime() 
); 
+1

+1 Bu arada yararlı DDL için. –

+0

(IMO) benzersiz tanımlayıcılara (kimlik sütunu işi yapar ve size daha iyi bir performans verir) gerek duymasa da, GUID'lerle bile SET @MyIdentity = NewSequentialID() kullanırsanız, kümelenmiş birincil anahtarlara sahip olabilirsiniz. Ayrıca, NewSequentialID() kimlik sütunları için varsayılan değer olarak kullanabilir ve Martin tarafından önerildiği gibi OUTPUT deyimini kullanarak eklenen değerler alabilirsiniz. – Niikola

cevap

13

O ancak uçlar için, zaten applicationID bir DEFAULT değerine sahip olsa bile, bu biraz daha fazla iş yapabileceğini oluyor : Esasen

DECLARE @MyIdentity uniqueidentifier; 
SET @MyIdentity = NewID(); 
INSERT INTO dbo.aspnet_Applications 
(
    ApplicationName, 
    LoweredApplicationName, 
    ApplicationId, 
    Description 
) 
VALUES 
(
    'x', 
    'x', 
    @MyIdentity, 
    'Dummy text' 
); 

SELECT @MyIdentity 

, sen önceden GUID set bu yüzden ne ekleyeceğinizi biliyorsunuz.

+0

harika çözüm! – GibboK

4

Sen geri eklenen değer (ler) almak için OUTPUT maddesini kullanabilirsiniz ama LBT's answer muhtemelen daha basit ve etkilidir. Eğer aşağıda bunun için composable DML kullanabilirsiniz Yabancı Key olmasaydı arada

DECLARE @ids table(id uniqueidentifier) 

INSERT INTO dbo.aspnet_Applications 
(
    ApplicationName, 
    LoweredApplicationName, 
    Description 
) 
OUTPUT INSERTED.ApplicationId into @ids 
VALUES 
(
    'x', 
    'x', 
    'Dummy text' 
) 

.

INSERT 
INTO dbo.aspnet_Users 
     (
       ApplicationId , 
       UserName  , 
       LoweredUserName, 
       MobileAlias , 
       IsAnonymous , 
       LastActivityDate 
     ) 
SELECT ApplicationId , 
     'Administrator', 
     'administrator', 
     ''    , 
     0    , 
     sysutcdatetime() 
FROM (INSERT 
     INTO dbo.aspnet_Applications 
       (
         ApplicationName  , 
         LoweredApplicationName, 
         Description 
       ) 
       OUTPUT INSERTED.ApplicationId VALUES 
       (
         'x', 
         'x', 
         'Dummy text' 
       ) 
     ) AS I 
İlgili konular