在具有外键关系的表中插入2行,而不知道主表的主键

时间:2014-08-08 21:00:12

标签: c# sql sql-server database visual-studio

我在SQL Server Manager 2014中有以下数据库方案。

Database scheme

我在Visual Studio中创建了一个C#-windows应用程序,我想插入一个新的订单行和一个新的订单。问题是两个表的主键,在服务器管理器中自动生成,所以我还没有订单表的主键的值,但我需要该值填入外键orderLine列。如何插入这两行。

亲切的问候

3 个答案:

答案 0 :(得分:5)

SCOPE_IDENTITY返回插入同一范围内的标识列的最后一个标识值。范围是一个模块:存储过程,触发器,函数或批处理。因此,如果两个语句在同一存储过程,函数或批处理中,则它们在同一范围内。

您可以使用SqlCommand.ExecuteScalar执行insert命令并在一个查询中检索新ID。

using (var con = new SqlConnection(ConnectionString)) {
    int newOrderID;
    var cmd = "INSERT INTO Order (column_name) VALUES (@Value) ;SELECT CAST(scope_identity() AS int)";
    using (var insertCommand = new SqlCommand(cmd, con)) {
        insertCommand.Parameters.AddWithValue("@Value", "bar");
        con.Open();
        newOrderID = (int)insertCommand.ExecuteScalar();
    }
}

这将允许您捕获最后生成的OrderId并在OrderLine表的Insert语句中使用它。

另一种选择是使用以下SQL代码:

string command = "INSERT INTO Order(totalPrice) OUTPUT INSERTED.ID VALUES(@totalPrice)" // this will be a parameter from your code

然后可以从以下位置获取OrderId:

Int32 orderId = (Int32) command.ExecuteScalar();

答案 1 :(得分:1)

如果您使用的是任何形式的直接SQL,则需要在插入订单后立即收到SCOPE_IDENTITY()值,然后使用该值插入您的行。

  1. INSERT INTO Order
  2. SELECT SCOPE_IDENTITY() AS NewId; OR RETURN SCOPE_IDENTITY(); OR DECLARE @OrderId INT = SCOPE_IDENTITY();
  3. INSERT INTO OrderLine
  4. 否则,使用Entity Framework,它将自动检索新ID并分配给依赖项。

答案 2 :(得分:1)

虽然scope_id()适用于单行,但您确实应该学习使用output子句,因为对于使用单个sql语句插入的多行,scope_id()是无用的。

有关使用输出子句的简单示例,请参阅此prior question

显然,这允许您检索的不仅仅是身份值。

ADDED

新的序列功能(2012年添加)也很有用,而不是使用身份。如果您来自其他数据库,这似乎是一个更自然的解决方案。

如果你想在几个表中共享一个序列,序列是非常有用的 - 尽管这是一个不常见的设计,我已经使用了几次。