2013-04-18 28 views
1

我有一个用VB.NET编写的ASP.NET页面,通过INNER JOIN使用SELECT语句将项目获取到GridView,并且还允许您将项目添加到发票。SQL_INSERT和Scope_Identity() - 获取记录ID

INNER JOINitemsproject_items获得数据。

SELECT 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 isSession("ProjectID")

(有一个外键project_items.item_id -> items.item_id。)

我有一个试图用SQL语句在VB.NET,试图同时插入到两个表。我试过是我试图让创造的最后一个记录的item_id并通过使用数据插入到另一个表(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 [email protected]" 
     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 
+0

你得到任何错误??? – mmpatel009

+0

只是用于调试目的的try/catch语句添加到上面的代码,并检查是否有任何异常。另外为什么关闭/打开两个命令之间的连接? – Steve

+0

你在调试中一行一行地运行它吗?你是否从第一个命令中获得预期的ItemID? –

回答

3

你为什么要在多条语句首先这样做呢?为什么不:

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 - 但内纳德正确地指出,选择一个而不是调用两个。)

因为我们现在知道,有一个明确的外键在这里,我们可以即使我们不能使用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 

将它放到存储过程中会更清晰。

+0

出现此错误:'OUTPUT INTO子句的目标表'dbo.project_items'不能位于(主键,外键)关系的任一侧。找到参考约束“FK__project_i__item ___ 1CBC4616'.' – Brian

0
ItemId = AddNewItemSQL.ExecuteScalar() 

     AddNewItemSQL.ExecuteNonQuery() 

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

由于您只从第一行检索到ItemID,应该在project_items中插入该ItemID,但上次插入到项目中的另一个将没有匹配的行。

而且 - 从按钮单击方法了年初完成部分Dim AddNewItemComm As String之前 - 在打开和关闭的DataReader,什么也不做它似乎完全没有必要的。