当ID是uniqueidentifier时返回新行的ID

时间:2015-09-04 20:14:41

标签: sql-server tsql ado.net

我创建了一个使用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吗?

2 个答案:

答案 0 :(得分:6)

SCOPE_IDENTITY()仅用于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();

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

答案 1 :(得分:1)

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

    }
}