当 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();
}
}
我创建了一个 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();
}
}