【问题标题】:Returning ID of new row when ID is uniqueidentifier当 ID 为 uniqueidentifier 时返回新行的 ID
【发布时间】:2015-09-04 20:14:41
【问题描述】:

我创建了一个使用uniqueidentifier 作为主键的SQL Server 表。我将默认值或绑定设置为newid()。 (我想为此列设置 身份规范,但 uniqueidentifier 类型不支持。)

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

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() 返回 null。看来,由于uniqueidentifier 不能是表的身份SCOPE_IDENTITY() 返回null@@IDENTITY 也是如此)。

好的,那么还有其他方法可以使用 ADO.NET 检索新添加的 ID 吗?

【问题讨论】:

  • 这是因为 SCOPE_IDENTITY 返回最后插入的 IDENTITY 值。您的表没有标识,因此 NULL 是唯一可以返回的内容。 guid 变得如此流行的一个原因是您可以在代码中定义它并将其传递给 sql server。我当然希望如果那是您的主键,它不是聚集索引。你也可以看看这篇文章。 blogs.msmvps.com/jcoehoorn/blog/2014/05/12/…

标签: sql-server tsql ado.net


【解决方案1】:

SCOPE_IDENTITY() 仅用于标识值,对于 guid 值,您需要将 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();

我个人会将整个事情放在一个存储过程中。

【讨论】:

  • 如果只输出一个值,使用 ExecuteScalar() 则不必添加输出参数。
【解决方案2】:

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

Return ID on INSERT?

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

已编辑以显示具体示例:

假设如下表:

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();

    }
}

【讨论】:

  • 我了解 OUTPUT 参数,但是您链接的页面上的建议与我现在遇到的问题相同。我仍然需要一种方法来获取新 ID,以便将其分配给 OUTPUT 参数。 (存储过程不是我正在做的最佳选择。)
  • 如果您查看答案,它确实可以回答问题。编辑废话,这样你就可以看到我在说什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
相关资源
最近更新 更多