0

我正在使用 sql server 2008,我在其中编写了一个存储过程,它在表中插入一些值,然后返回这些插入的值。我用nvarchar作主键。因此,为了选择最后插入的值,我正在使用scopeidentity()函数,但问题是它正在插入值但没有返回最后插入的值。代码如下:

CREATE PROCEDURE cms_AddOwnerSession
@sessionId nvarchar(max),
@ownerId int,
@ownerName nvarchar(50),
@username nvarchar(30),
@password nvarchar(30)

AS
BEGIN

IF(@sessionId <> NULL)
    BEGIN
        INSERT INTO OwnerSession
        (SessionId,
        OwnerId,
        OwnerName,
        Username,
        [Password])
        VALUES
        (@sessionId,
        @ownerId,
        @ownerName,
        @username,
        @password)
        SET @sessionId = SCOPE_IDENTITY()
    END
    SELECT
        ISNULL (SessionId,'NULL')   'sessionId',
        ISNULL (OwnerId,0)          'ownerId',
        ISNULL (OwnerName,'')       'ownerName',
        ISNULL (Username,'')        'username',
        ISNULL ([Password],'')      'password' 
    FROM OwnerSession
    WHERE SessionId = @sessionId
END
GO
4

3 回答 3

2

SCOPE_IDENTITY返回最后生成的IDENTITY列值。它与您自己提供的数据无关。它与第一列不匹配,并且与名称中包含“ID”的第一列不匹配。(我认为其中之一就是这里的误解)。

于 2013-07-28T09:58:01.333 回答
1

scope_identity()即使您使用了列,在您的上下文中也不会工作,IDENTITY因为您试图访问插入行的过程范围之外的值。为了可靠地获取插入过程中的值,您需要将其记录在同一语句中,或者至少在IDENTITY使用值的情况下记录在相同的过程中。

在您的情况下,您可以获取提供的值并将其返回给调用者,或者您可以使用该OUTPUT子句来执行此操作。

不同的IDENTITY相关功能和不足的介绍可以在这里找到:http ://sqlity.net/en/351/identity-crisis/

那篇文章还展示了如何使用该OUTPUT条款来处理所有这些不足。

但请始终记住,如果插入完成并且您在执行期间没有捕获该值,则无法保证之后您将获得正确的值 - 与使用的方法无关。

于 2013-07-28T11:05:50.727 回答
1

scope_identity()返回在您的 SCOPE 中生成的最后一个IDENTITY值。SessionId不是一个身份。
小心使用scope_identity()、@@identity 和 IDENT_CURRENT值:

@@IDENTITY、SCOPE_IDENTITY 和 IDENT_CURRENT 是相似的函数,因为它们都返回插入到表的 IDENTITY 列中的最后一个值。

@@IDENTITY 和 SCOPE_IDENTITY 返回当前会话中任何表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回当前范围内的值;@@IDENTITY 不限于特定范围。

IDENT_CURRENT 不受范围和会话限制;它仅限于指定的表。IDENT_CURRENT 返回为任何会话和任何范围内的特定表生成的标识值。

于 2013-07-28T10:05:43.840 回答