SQL - INSERT with Scope_Identity() - 获取记录ID

时间:2013-04-18 12:37:28

标签: asp.net sql vb.net tsql sql-server-2012

我有一个用VB.NET编写的ASP.NET页面,通过GridView使用SELECT语句将项目放入INNER JOIN,并允许您添加项目到INNER JOIN发票。

itemsproject_itemsSELECT Items.item_id, Items.item_name, Items.item_cost, project_items.item_quantity FROM Items INNER JOIN project_items ON items.item_id = project_items.item_id WHERE project_items.project_id = @parameter 获取数据。

@parameter is

Session("ProjectID") project_items.item_id -> items.item_id

(有一个外键item_id。)

我试图在VB.NET中使用SQL语句尝试同时插入两个表。我尝试的是尝试获取最后创建的记录的project_items并使用该数据插入另一个表(Protected Sub btnAddItem_Click(sender As Object, e As EventArgs) Handles btnAddItem.Click Dim conn As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True") Dim addItemComm As String = "SELECT item_id FROM project_items WHERE project_id=@ProjectID" Dim user_id_select As New Integer Dim addItemSQL As New SqlCommand conn.Open() addItemSQL = New SqlCommand(addItemComm, conn) addItemSQL.Parameters.AddWithValue("@ProjectID", Convert.ToInt32(Session("ProjectID"))) Dim datareader As SqlDataReader = addItemSQL.ExecuteReader() datareader.Close() conn.Close() Dim AddNewItemComm As String = "INSERT INTO Items (item_name, item_cost, item_code) VALUES (@ItemName, @ItemCost, @ItemCode); SELECT SCOPE_IDENTITY()" Dim AddNewItem2Comm As String = "INSERT INTO project_items (item_id, project_id, item_quantity) VALUES (@ItemID, @ProjectID, @ItemQuantity) " Dim AddNewItemSQL As New SqlCommand conn.Open() AddNewItemSQL = New SqlCommand(AddNewItemComm, conn) AddNewItemSQL.Parameters.AddWithValue("@ItemName", txtItemName.Text.Trim) AddNewItemSQL.Parameters.AddWithValue("@ItemCost", Convert.ToInt32(txtItemCost.Text)) AddNewItemSQL.Parameters.AddWithValue("@ItemCode", txtItemCost.Text.ToString.ToUpper) Dim ItemId As Integer ItemId = AddNewItemSQL.ExecuteScalar() AddNewItemSQL.ExecuteNonQuery() conn.Close() conn.Open() AddNewItemSQL = New SqlCommand(AddNewItem2Comm, conn) AddNewItemSQL.Parameters.AddWithValue("@ItemID", ItemId) AddNewItemSQL.Parameters.AddWithValue("@ProjectID", Convert.ToInt32(Session("ProjectID"))) AddNewItemSQL.Parameters.AddWithValue("@ItemQuantity", Convert.ToInt32(txtItemQuantity.Text)) AddNewItemSQL.ExecuteNonQuery() conn.Close() End Sub )。但是,数据仅输入第一个表格。

知道我能做什么吗?

这是代码:

{{1}}

2 个答案:

答案 0 :(得分:4)

为什么你首先在多个陈述中这样做?为什么不:

INSERT dbo.Items (item_name,  item_cost, item_code) 
  OUTPUT inserted.ItemID, @ProjectID, @ItemQuantity 
  INTO dbo.project_items(item_id, project_id, item_quantity)
VALUES (@ItemName, @ItemCost, @ItemCode);

现在您只需拨打一个ExecuteNonQuery(),您的应用就不必关心实际生成的SCOPE_IDENTITY()值了。 (如果你愿意,你仍然可以使用SCOPE_IDENTITY()检索ExecuteScalar - 但正如Nenad正确指出的那样,选择一个而不是同时调用它们。)

由于我们现在知道这里有一个显式外键,即使我们不能使用OUTPUT子句,我们仍然可以将C#代码减少到一个调用。

DECLARE @i INT;

INSERT dbo.Items (item_name,  item_cost, item_code) 
  SELECT @ItemName, @ItemCost, @ItemCode;

SELECT @i = SCOPE_IDENTITY();

INSERT dbo.project_items(item_id, project_id, item_quantity)
  SELECT @i, @ProjectID, @ItemQuantity 

SELECT @i; -- if necessary

将它放入存储过程会更加清晰。

答案 1 :(得分:0)

ItemId = AddNewItemSQL.ExecuteScalar()

        AddNewItemSQL.ExecuteNonQuery()

这两行彼此相邻将执行两次命令。你应该删除第二个 - ExecuteNonQuery。这将使您的数据在Items中插入两次 - 两行相同但ID不同。

由于您只从第一行检索ItemID,因此应将其插入project_items,但最后一次插入项目中的另一行将没有匹配的行。

此外 - 从Dim AddNewItemComm As String之前的按钮点击方法开始的完整部分 - 您打开和关闭DataReader并且不执行任何操作似乎完全没必要。