我创建了一个使用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吗?
答案 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输出。即使这个页面没有关注你的特定问题,它应该给你一些线索:
我的正常方向是存储过程,但您可以像完成一样链接命令。存储过程使事情变得更容易,因为您可以为过程创建输出参数,但输出值可以正常工作。
已编辑以显示具体示例:
假设下表:
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();
}
}