2010-08-11 5 views
7

Tôi đang bối rối với một truy vấn.Lấy hàng cuối cùng được chèn với Uniqueidentifier rằng nó không phải là IDENTITY

tôi cần tìm hiểu hàng LAST được thêm vào trong một bảng với một cột với datatype uniqueIdentifier cột là: aspnet_Applications.ApplicationId Ghi chú: Cột này uniqueIdentifier nó là KHÔNG và SẮC Cột.

Tôi cũng cần lấy hàng cuối cùng chèn và cập nhật nó vào một bảng khác nhau aspnet_Users.ApplicationId

Tôi cố gắng để sử dụng SCOPE_IDENTITY trong MS SQL 2008 nhưng không làm việc vì SCOPE_IDENTITY đang làm việc chỉ với cột IDENTITY.

Ở đây mã của tôi. Bất kỳ ý tưởng?

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 Đối với DDL hữu ích bằng cách này. –

+0

Mặc dù (IMO) bạn không cần số nhận dạng duy nhất (cột nhận dạng sẽ thực hiện công việc và cung cấp cho bạn hiệu suất tốt hơn), ngay cả với GUID bạn có thể có các khóa chính được nhóm nếu bạn sử dụng SET @MyIdentity = NewSequentialID(). Bạn cũng có thể sử dụng NewSequentialID() làm giá trị mặc định cho các cột ID và nhận các giá trị được chèn bằng cách sử dụng câu lệnh OUTPUT như được đề xuất bởi Martin. – Niikola

Trả lời

13

Đó là một công việc ít hơn, nhưng đối với chèn của bạn, mặc dù bạn đã có một giá trị DEFAULT trên ApplicationID, bạn có thể làm điều này:

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

SELECT @MyIdentity 

Về cơ bản, bạn thiết lập các GUID trước, vì vậy bạn đã biết những gì bạn sẽ được chèn.

+0

giải pháp tuyệt vời! – GibboK

4

Bạn có thể sử dụng mệnh đề OUTPUT để lấy lại (các) giá trị được chèn vào nhưng LBT's answer có lẽ đơn giản và hiệu quả hơn.

DECLARE @ids table(id uniqueidentifier) 

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

Bằng cách này nếu không phải khóa ngoại, bạn có thể sử dụng composable DML cho điều này như dưới đây.

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