【问题标题】:Retrieve last row inserted with Uniqueidentifier that it is not IDENTITY检索使用 Uniqueidentifier 插入的最后一行,它不是 IDENTITY
【发布时间】:2010-08-11 19:46:38
【问题描述】:

我对一个问题感到困惑。

我需要找出在表中添加的最后一行,其中包含数据类型为 Uniqueidentifier 的列 列是: aspnet_Applications.ApplicationId 备注:此列的 Uniqueidentifier 它是 NOT 和 IDENTITY 列。

我还需要插入最后一行并在另一个表上更新它 aspnet_Users.ApplicationId

我尝试在 MS SQL 2008 中使用 SCOPE_IDENTITY 但不起作用,因为 SCOPE_IDENTITY 仅适用于 IDENTITY 列。

这是我的代码。有什么想法吗?

    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 顺便说一下有用的 DDL。
  • 虽然(IMO)您不需要唯一标识符(身份列可以完成这项工作并为您提供更好的性能),即使使用 GUID,如果您使用 SET @MyIdentity = NewSequentialID,您也可以拥有集群主键()。您还可以使用 NewSequentialID() 作为 ID 列的默认值,并使用 Martin 提出的 OUTPUT 语句获取插入的值。

标签: sql sql-server database tsql sql-server-2008


【解决方案1】:

这需要更多的工作,但是对于您的插入,即使您已经在 ApplicationID 上设置了 DEFAULT 值,您也可以这样做:

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

SELECT @MyIdentity

基本上,您事先设置了 GUID,因此您已经知道要插入什么。

【讨论】:

    【解决方案2】:

    可以使用OUTPUT 子句来取回插入的值,但LBT's answer 可能更直接有效。

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

    顺便说一句,如果不是外键,您可以使用composable DML 如下所示。

    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
    

    【讨论】:

    • 请注意,没有 INTO 的 OUTPUT 子句与触发器不兼容。我们使用了这种解决方案,然后在打开数据库复制时遇到了this error
    猜你喜欢
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2010-12-31
    相关资源
    最近更新 更多