使用刚刚创建的多个ID插入多个表

时间:2011-09-29 19:52:25

标签: asp.net sql vb.net insert

我不得不在我的数据库中添加另一个表,现在我需要返回并更新允许插入多个表的页面。我没有写这个页面,所以我正在尝试清理所有内容,但有些部分我并不理解。现在我打破了页面,它只插入一个表中。我插入的第一个。

ProductName:进入产品表

描述:作为数据进入Picklist表.....它还应该根据PicklistID生成一个插入到营销表中,这是一个标识列。营销表告诉Picklist表它正在寻找描述。

价格:进入产品表

类别:进入CategoryLink表,该表还插入最近生成的ProductID。

公司:进入CompanyLink表,该表还插入最近生成的ProductID。

目标受众:进入TargetLink表,该表还会插入最近生成的ProductID。

状态:进入产品表

enter image description here

Protected Sub submitButton_Click(ByVal sender As Object, 
ByVal e As System.EventArgs) Handles submitButton.Click
    Dim CategoryID As String = txtCategoryID.Value
    Dim CompanyIDs As New ArrayList
    'Get selected companies-----
    Dim CompanyCount As Integer = CompanyCheckbox.Items.Count
    For i As Integer = 0 To CompanyCount - 1
        If CompanyCheckbox.Items(i).Selected Then
            CompanyIDs.Add(CompanyCheckbox.Items(i).Value)
        End If
    Next
    'Get selected targets---
    Dim TargetIDs As New ArrayList
    Dim TargetCount As Integer = TargetCheckbox.Items.Count
    For i As Integer = 0 To TargetCount - 1
        If TargetCheckbox.Items(i).Selected Then
            TargetIDs.Add(TargetCheckbox.Items(i).Value)
        End If
    Next
    'Get Status---
    Dim Status As String = Nothing
    If StatusCheckbox.Checked Then
        Status = "1"
    Else
        Status = "0"
    End If
    'SQL Insert: Product Table
    Dim sqlInsertProduct As String = "IF NOT EXISTS (SELECT * FROM Product 
    WHERE ProductName= @ProductName) 
    BEGIN INSERT INTO Product 
    (ProductName, Status, CreateDate, ModifyDate, CreateUser, ModifyUser, Price) 
    VALUES (@ProductName, @Status ,getdate(),getdate(), @CreateUser, @ModifyUser,
    @Price) END;
    INSERT INTO Picklist (Title, Data) VALUES ('About this product', @Data);"

    'Create SQL Connection
    Using cn As New 
    SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings
    ("LocalSqlServer").ConnectionString)

        Using cmd As New SqlCommand(sqlInsertProduct, cn)

            cmd.Parameters.Add(New SqlParameter("@ProductName", 
            txtNewProductName.Text))
            cmd.Parameters.Add(New SqlParameter("@Status", StatusCheckbox.Checked))
            cmd.Parameters.Add(New SqlParameter("@Price", txtPrice.Text))
            cmd.Parameters.Add(New SqlParameter("@Data", txtProductDesc.Text))
            cmd.Parameters.Add(New SqlParameter("@CreateUser",
            System.Web.HttpContext.Current.User.Identity.Name))
            cmd.Parameters.Add(New SqlParameter("@ModifyUser",
            System.Web.HttpContext.Current.User.Identity.Name))
            cn.Open()
            cmd.ExecuteNonQuery()
        End Using
        'Get the productID of the newly inserted product
        Dim sqlGetID As String = "SELECT @@IDENTITY"
        Dim ProductID As String = Nothing
        Dim cmdGetID As New SqlCommand(sqlGetID, cn)
        Dim myReader As SqlDataReader = cmdGetID.ExecuteReader()
        While myReader.Read
            If IsDBNull(myReader(0)) Then
                ProductID = ""
            Else
                ProductID = myReader(0)
            End If
        End While
        myReader.Close()
        cn.Close()

        'SQL Insert: Marketing Table
        Dim sqlInsertMarketing As String = "INSERT INTO Marketing (ProductID, 
        MarketingTypeID, MarketingTitle, MarketingData) VALUES ('" & ProductID & "', 2,
        'Description', scope_identity())"
        'SQL Insert: Category Table
        If CategoryID <> Nothing Then
            Dim sqlInsertCategory As String = "INSERT INTO CategoryLink (CategoryID,
            ProductID) VALUES (@CategoryID,'" & ProductID & "')"
            Using cmdInsertCategory As New SqlCommand(sqlInsertCategory, cn)
                cmdInsertCategory.Parameters.Add(New SqlParameter("@CategoryID",
                txtCategoryID.Value))
                cn.Open()
                cmdInsertCategory.ExecuteNonQuery()
            End Using
            cn.Close()
        End If
        If CompanyIDs.Count > 0 Then
            For i = 0 To CompanyIDs.Count - 1
                Dim sqlInsertCompany = "INSERT INTO CompanyLink (CompanyID, ProductID)
                VALUES ('" & CompanyIDs(i) & "','" & ProductID & "')"
                Using cmdInsertCompany As New SqlCommand(sqlInsertCompany, cn)
                    cn.Open()
                    cmdInsertCompany.ExecuteNonQuery()
                End Using
                cn.Close()
            Next

        End If
        If TargetIDs.Count > 0 Then
            For i = 0 To TargetIDs.Count - 1
                Dim sqlInsertTarget = "INSERT INTO TargetLink (TargetID, ProductID) 
                VALUES ('" & TargetIDs(i) & "','" & ProductID & "')"
                Using cmdInsertTarget As New SqlCommand(sqlInsertTarget, cn)
                    cn.Open()
                    cmdInsertTarget.ExecuteNonQuery()
                End Using
                cn.Close()
            Next
        End If

    End Using

Response.Write("<script type='text/javascript'>{ alert('Product added successfully'); 
document.location.href = 'AddProduct.aspx'; }</script>")
End Sub
End Class

就像我之前说的那样,只有进入Product表的插入才有效。在我添加Picklist表并尝试重新连接所有内容之前,整个页面都有效。代码很邋and,没有参数,所以这也可能是我搞砸了,因为我仍在努力学习如何使用它们。如果我需要包含其他信息,我可以这样做。我不知道如何详细地发表这篇文章。感谢

更新:

除了INSERT到Marketing表之外,我已经获得了所有INSERT的功能。我真的很感谢能够帮助我将PicklistID插入到Marketing表的MarketingData列中的人

enter image description here

2 个答案:

答案 0 :(得分:3)

如果您只有一个身份值可以使用SCOPE_IDENTITY(),请不要使用@@ IDENTITY。 @@ IDENTITY的问题在于它总是返回最后一个标识值,即使它来自另一个“范围”。例如,您插入到表中并生成标识值,然后触发一个触发器,该触发器插入具有标识的日志表。然后你调用@@ IDENTITY,猜猜你得到的是日志表标识值,它是最后一次。 SCOPE_IDENTITY()为您提供本地范围内的最后一个。

但是,如果由于在一个语句中插入多行而需要捕获多个标识值,则必须使用OUTPUT clause。它适用于INSERT,UPDATE和DELETE,但这是一个更新的示例:view the changed values after an update statement

答案 1 :(得分:1)

这是代理人的缺点之一,即更难以执行批量创建实体。我自己避免使用代理人,但经常遇到这个问题。我的一般方法是使用临时表将系统生成的代理映射到其自然键。

假设这种稍微简化的结构:

CREATE TABLE Products 
(
 ProductName VARCHAR(20) NOT NULL UNIQUE,  -- natural key
 ProductID INTEGER IDENTITY(1, 1) NOT NULL UNIQUE  -- surrogate
);

CREATE TABLE PickLists
(
 PicklistDescription VARCHAR(30) NOT NULL UNIQUE,  -- natural key
 PicklistID INTEGER IDENTITY(50, 50) NOT NULL UNIQUE  -- surrogate
);

CREATE TABLE Marketing
(
 ProductID INTEGER NOT NULL UNIQUE REFERENCES Products (ProductID), 
 PicklistID INTEGER NOT NULL UNIQUE REFERENCES PickLists (PicklistID), 
 MarketingComment VARCHAR(40) NOT NULL
);

以下是使用vanilla Standard SQL-92的基本概要(IDENTITY关键字除外!):

(注意:自然键是在DBMS之外生成的,代理是DBMS生成的值)

CREATE TABLE StagingMarketing
(
 ProductName VARCHAR(20) NOT NULL UNIQUE, 
 PicklistDescription VARCHAR(30) NOT NULL UNIQUE, 
 MarketingComment VARCHAR(40) NOT NULL
);

-- Bulk insert staging table using natural key values
INSERT INTO StagingMarketing (ProductName, PicklistDescription, MarketingComment)
   VALUES ('Widget55', 'Stuff22', 'Prototype');
INSERT INTO StagingMarketing (ProductName, PicklistDescription, MarketingComment)
   VALUES ('Widget99', 'Stuff152', 'Research');

-- Update referenced tables
INSERT INTO Products (ProductName)
   SELECT ProductName FROM StagingMarketing;
INSERT INTO PickLists (PicklistDescription)
   SELECT PicklistDescription FROM StagingMarketing;

-- Finally, update referencing table
INSERT INTO Marketing (ProductID, PicklistID, MarketingComment)
   SELECT P.ProductID, L.PicklistID, S.MarketingComment
     FROM StagingMarketing S
          INNER JOIN Products P
             ON P.ProductName = S.ProductName
          INNER JOIN PickLists L
             ON L.PicklistDescription = S.PicklistDescription;

-- Cleanup
DELETE FROM StagingMarketing;

SELECT * FROM Marketing;

P.S。如果设计师选择在没有自然键的情况下使用IDENTITY作为人工键,那么你就是在小河上。

相关问题