当 ID 为 uniqueidentifier 时返回新行的 ID

Returning ID of new row when ID is uniqueidentifier

我创建了一个 SQL 服务器 table,它使用 uniqueidentifier 作为主键。我将 默认值或绑定 设置为 newid()。 (我想为此列设置 Identity Specification,但不支持 uniqueidentifier 类型。)

然后我使用 ADO.NET 向此 table 添加一行。

SqlComment command = new SqlCommand("INSERT INTO [User] (Name) VALUES (@name); 
                                     SELECT SCOPE_IDENTITY()", Connection);
command.Parameters.AddWithValue("@name", "Joe Smoe");
Guid userId = (Guid)command.ExecuteScalar();

然而,最后一行失败了,因为ExecuteScaler() returns null。看来,由于 uniqueidentifier 不可能是 table 的 身份 SCOPE_IDENTITY() returns null(如@@IDENTITY).

好的,那么有没有另一种方法可以使用 ADO.NET 来检索新添加的 ID?

SCOPE_IDENTITY() 仅用于标识值,对于 guid 值,您需要使用带有 table 变量的 OUTPUT 子句。

DECLARE @NewGuid TABLE(NewValue UNIQUEIDENTIFIER);

INSERT INTO [User] (Name)
OUTPUT inserted.pk_ColName INTO  @NewGuid(NewValue)
VALUES (@name); 

SELECT * FROM @NewGuid  --<-- here you will have the new GUID Value

C# 代码看起来像....

string cmd = "DECLARE @NewGuid TABLE(NewValue UNIQUEIDENTIFIER);
                INSERT INTO [User] (Name)
                OUTPUT inserted.pk_ColName INTO  @NewGuid(NewValue)
                VALUES (@name); 
                SELECT @newID = NewValue FROM @NewGuid;"


SqlCommand command = new SqlCommand(cmd, Connection);
cmd.Parameters.AddWithValue("@name", "Joe Smoe");
cmd.Parameters.Add("@newID", SqlDbType.UniqueIdentifier).Direction = ParameterDirection.Output;
Guid userId = (Guid)cmd.ExecuteScalar();

就我个人而言,我会把整个事情放在一个存储过程中。

Scope_Identity() 专注于 IDENTITY 字段,因此它永远不会产生任何结果。您需要改为从 INSERTED 输出。尽管此页面并未针对您的特定问题,但它应该可以为您提供一些线索:

Return ID on INSERT?

我的正常方向是存储过程,但您可以像您所做的那样链接命令。存储过程使事情变得更容易一些,因为您可以为该过程创建一个输出参数,但输出一个值工作正常。

已编辑以显示具体示例:

假设以下 table:

CREATE TABLE [dbo].[MyTable]
(
    [Id] [uniqueidentifier] PRIMARY KEY NOT NULL DEFAULT NEWID(),
    [Name] [varchar](50) NOT NULL,
)

以下程序将输出从 NewID() 创建的新 GUID:

class Program
{
    static void Main(string[] args)
    {

        var connString = ConfigurationManager.ConnectionStrings["testDB"].ToString();
        var cmdString = "INSERT INTO MyTable (Name) OUTPUT Inserted.Id VALUES ('Name')";

        var connection = new SqlConnection(connString);
        var command = new SqlCommand(cmdString, connection);

        Guid outputValue;

        try
        {
            connection.Open();
            //Convert to Guid here instead
            Console.WriteLine(command.ExecuteScalar().ToString());
        }
        finally
        {
            connection.Dispose();
        }

        Console.Read();

    }
}