繁体   English   中英

在SQL INSERT命令期间/之后返回标识列的值

[英]Returning the value of an identity column during/after SQL INSERT command

使用VS 2010和ASP.NET,.NET 3.0和C#...

当我使用System.Web.UI.WebControls.SqlDataSource并调用其Insert()方法插入新行,并且该表具有标识列时,我希望我的方法返回该列的值。

例如,在我的SQL 2005表中,我得到了:

  • 顾客ID
  • 客户名字
  • 客户姓氏

其中Customer.Id是标识列。

当我调用方法InsertNewCustomerRecord(“ John”,“ Smith”)时,我希望能够返回在数据库中自动生成的Customer.Id。

很抱歉提出这样一个粗略的问题。 让我知道是否可以添加更好的细节。 谢谢。

如果您使用的是SQL Server 2005或更高版本,则可以使用OUTPUT子句在单个语句中执行此操作:

Create Table Foo    (
                    Id int not null identity(1,1)
                    , Name varchar(50) null
                    , ....
                    )

Insert Foo(Name)
    Output inserted.Id, inserted.Name
Select 'Foo'
Union All Select 'Bar'
....

如果使用的是SQL Server 2000,则应这样使用SCOPE_IDENTITY

Insert Foo(Name)
Select 'Foo'

Select SCOPE_IDENTITY()

请注意,我一次只能使用此方法执行一次插入操作,因为我们要在Insert语句之后立即调用SCOPE_IDENTITY

如果使用的是SQL Server 2000之前的版本, @@IDENTITY使用@@IDENTITY

Insert Foo(Name)
Select 'Foo'

Select @@Identity

问题是如果表上有触发器,@@ Identity会做一些时髦的事情。

编辑您询问如何在C#中使用此信息。 您将像调用SELECT查询一样使用它:

var connString = ConfigurationManager.ConnectionStrings["MyConnectionStringName"].ConnectionString;
DataTable newData;

using ( var conn = new SqlConnection( connString ) )
{
    conn.Open();
    const string sql = "Insert Foo(Name) Output inserted.Id, inserted.Name Values(@Name)";
    using ( var cmd = new SqlCommand( sql, conn ) )
    {
        cmd.Parameters.AddWithValue("@Name", "bar");
        using ( var da = new SqlDataAdapter( cmd ) )
        {
            da.Fill( newData );
        }
    }
}

在这里,我假设您在配置文件中具有MyConnectionStringName的connectionStrings条目。 另外,您将需要添加对System.Configuration的引用才能使用ConfigurationMananager类。 我没有检查此代码,但它应该非常接近您的需求。 在这种情况下,我将直接编写查询。 还有其他解决方案,例如使用DataSource控件和设置SelectCommand

我宁愿使用SCOPE_IDENTITY(Transact-SQL)

SCOPE_IDENTITY和@@ IDENTITY返回在当前会话的任何表中生成的最后一个标识值。 但是,SCOPE_IDENTITY返回仅在当前作用域内插入的值。 @@ IDENTITY不限于特定范围。

请注意,@@ IDENTITY可能不会返回您期望的结果

例如,有两个表T1和T2,并且在T1上定义了INSERT触发器。 当在T1中插入一行时,触发器将触发并在T2中插入一行。 此方案说明了两个作用域:触发器在T1上的插入和T2在T2上的插入。

假设T1和T2都具有标识列,则@@ IDENTITY和SCOPE_IDENTITY将在T1上的INSERT语句的末尾返回不同的值。 @@ IDENTITY将返回插入当前会话中任何范围的最后一个标识列值。 这是在T2中插入的值。 SCOPE_IDENTITY()将返回插入到T1中的IDENTITY值。 这是同一作用域中发生的最后一次插入。 如果在作用域中对标识列的任何INSERT语句发生之前调用该函数,则SCOPE_IDENTITY()函数将返回空值。

Insert方法使用InsertCommand属性...

因此,将InsertCommand修改为

INSERT Mytable (col1, col2) VALUES (@param1, @parame);SELECT SCOPE_IDENTITY();

或(对于SQL Server 2005+)

INSERT Mytable (col1, col2) OUTPUT INSERTED.IDCol VALUES (@param1, @param2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM