2015-09-04 68 views
0

我创建了一个使用uniqueidentifier作为主键的SQL Server表。我将默认值或绑定设置为newid()。 (我想为此列设置标识规范,但不支持uniqueidentifier类型。)当ID是唯一标识符时返回新行的ID

然后我使用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

这是因为SCOPE_IDENTITY返回最后插入的IDENTITY值。你的表没有标识,所以NULL是唯一可以返回的东西。 Guid已经变得如此流行的一个原因是因为你可以在你的代码中定义它并将它传递给sql server。我当然希望如果这是你的主键,它不是聚集索引。你也可以看看这篇文章。 http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ –

回答

5

SCOPE_IDENTITY()仅用于标识值,对于需要使用OUTPUT子句和表变量的guid值。

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

个人而言,我会把整个事情中的存储过程。

+0

如果您使用ExecuteScalar()if,则不必添加输出参数if你只输出一个值。 –

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

    } 
} 
+0

我了解OUTPUT参数,但是您链接的页面上的建议与我现在遇到的问题相同。我仍然需要一种方法来获取新ID以便将其分配给OUTPUT参数。 (存储过程不是我正在做的最好的选择。) –

+0

如果你看到答案,它确实回答了这个问题。编辑拉扯废话,让你可以看到我在说什么。 –