如何在ADO.NET中使用存储过程在同一个表中添加多行?

时间:2017-02-21 01:36:44

标签: sql-server ado.net

这些是我的桌子设计:

CREATE TABLE Member
(
     Member_No UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
     Name VARCHAR(50) NOT NULL,
     Email VARCHAR(50) NOT NULL,
     Phone BIGINT NOT NULL,
     Username VARCHAR(50) NOT NULL,
     Password VARCHAR(50) NOT NULL
)

CREATE TABLE Toy
(
     Toy_No UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
     Toy_Image VARBINARY(MAX) NOT NULL,
     Toy_Name VARCHAR(50) NOT NULL,
     Anime_Image VARBINARY(MAX) NOT NULL,
     Anime_Name VARCHAR(50) NOT NULL,
     Toy_Distributor_Image VARBINARY(MAX) NOT NULL,
     Toy_Distributor VARCHAR(50) NOT NULL,
     Price INTEGER NOT NULL,
     Quantity INTEGER NOT NULL
)

CREATE TABLE Cart
(
     Cart_No UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
     Toy_No UNIQUEIDENTIFIER NOT NULL,
     Member_No UNIQUEIDENTIFIER NOT NULL,
     Total_Quantity INTEGER,
     Total_Price INTEGER,

     CONSTRAINT FK_ToyNo
         FOREIGN KEY(Toy_No) REFERENCES Toy(Toy_No),
     CONSTRAINT FK_MemberNo
         FOREIGN KEY(Member_No) REFERENCES Member(Member_No)
)

CREATE TABLE Toy_Purchase
(
     Toy_Purchase_No UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
     Cart_No UNIQUEIDENTIFIER NOT NULL,
     Toy_No UNIQUEIDENTIFIER NOT NULL,
     Member_No UNIQUEIDENTIFIER NOT NULL,
     Total_Quantity INTEGER NOT NULL,
     Total_Price INTEGER NOT NULL,
     Credit_Card_No BIGINT NOT NULL,
     Purchase_Date DATETIME DEFAULT GETDATE() NOT NULL,

     CONSTRAINT FK_CartNo
         FOREIGN KEY(Cart_No) REFERENCES Cart(Cart_No),
     CONSTRAINT FkToyNo
         FOREIGN KEY(Toy_No) REFERENCES Toy(Toy_No),
     CONSTRAINT FkMemberNo
         FOREIGN KEY(Member_No) REFERENCES Member(Member_No)
 )

此处需要注意的一件重要事情是,Total_Quantity表中Total_PriceCart中记录的值将被传递并插入Total_QuantityTotal_Price } Toy_Purchase表通过一个名为PurchaseToys的存储过程,我将在最后演示。

这是我的名为AddToCart的存储过程,我将选择具有一个或多个数量的不同玩具,然后添加到购物车中。

CREATE PROCEDURE AddToCart
    @CartNo UNIQUEIDENTIFIER OUTPUT,
    @ToyNo UNIQUEIDENTIFIER OUTPUT,
    @MemberNo UNIQUEIDENTIFIER OUTPUT,
    @TotalQuantity INTEGER,
    @TotalPrice INTEGER OUTPUT
AS
BEGIN
    SET @CartNo = NEWID()
    SET @ToyNo = (SELECT Toy_No FROM Toy)
    SET @MemberNo = (SELECT Member_No FROM Member)
    SET @TotalPrice = @TotalQuantity*(SELECT Price FROM Toy WHERE Toy_No=@ToyNo)

    INSERT INTO Cart(Cart_No, Toy_No, Member_No, Total_Quantity, Total_Price)
    VALUES(@CartNo, @ToyNo, @MemberNo, @TotalQuantity, @TotalPrice)
END

这是我的名为DisplayCart的存储过程,它会显示我在购买之前添加到购物车中的玩具商品列表。

CREATE PROCEDURE DisplayCart
AS
BEGIN
    SELECT 
        Toy_Image, Toy_Name, Total_Quantity, Total_Price
    FROM 
        Toy, Cart
    WHERE 
        Toy.Toy_No = Cart.Toy_No
END

这是我的名为PurchaseToys的存储过程。只有在我输入信用卡号后,然后点击网站上的确认付款按钮,才会执行此程序。

CREATE PROCEDURE PurchaseToys
    @ToyPurhcaseNo UNIQUEIDENTIFIER OUTPUT,
    @CartNo UNIQUEIDENTIFIER OUTPUT,
    @ToyNo UNIQUEIDENTIFIER OUTPUT,
    @MemberNo UNIQUEIDENTIFIER OUTPUT,
    @TotalQuantity INTEGER OUTPUT,
    @TotalPrice INTEGER OUTPUT,
    @CreditCardNo BIGINT,
    @PurchaseDate DATETIME OUTPUT
AS
BEGIN
    SET @ToyPurhcaseNo = NEWID()
    SET @CartNo = (SELECT Cart_No FROM Cart)
    SET @ToyNo = (SELECT Toy_No FROM Toy)
    SET @MemberNo = (SELECT Member_No FROM Member)
    SET @TotalQuantity = (SELECT Total_Quantity FROM Cart WHERE Cart_No = @CartNo) -- I'm planning to pass the value of Total_Quantity in Toy_Purchase table from Total_Quantity of Cart table
    SET @TotalPrice = (SELECT Total_Price FROM Cart WHERE Cart_No = @CartNo)  -- I'm planning to pass the value of Total_Price in Toy_Purchase table from Total_Price of Cart table
    SET @PurchaseDate = GETDATE()

    INSERT INTO Toy_Purchase (Toy_Purchase_No, Cart_No, Toy_No, Member_No, Total_Quantity, Total_Price, Credit_Card_No, Purchase_Date)
    VALUES (@ToyPurhcaseNo, @CartNo, @ToyNo, @MemberNo, @TotalQuantity, @TotalPrice, @CreditCardNo, @PurchaseDate)

    UPDATE Toy
    SET Quantity = Quantity - Total_Price 
    FROM Toy, Toy_Purchase
    WHERE Toy.Toy_No = Toy_Purchase.Toy_No
END

通常,如果查看名为PurchaseToys的此存储过程的逻辑,它将仅在Toy_Purchase表中插入单行,并且Quantity列的Toy列值将减少为只有一个玩具。

但是,我想根据我选择的玩具数量在Toy_Purchase表中插入多行。例如,如果我购买了2个不同的玩具,则存储过程应在Toy_Purchase表中插入2行,Quantity表中的Toy列值将减少2个不同的玩具。

如果我购买了4种不同的玩具,则存储过程应在Toy_Purchase表中插入4行,并且玩具表中的Quantity列值将减少4种不同的玩具。

那么如何确保在Toy_Purchase表中插入多行,并且通过ADO.NET中的存储过程减少Quantity列值以获取不同选定玩具的数量?

1 个答案:

答案 0 :(得分:1)

如果您想避免为每一行调用存储过程,那么您可以选择几个选项。

您可以使用C#中的SQLBulkCopy方法将数据表作为参数传递给表。 如果您仍希望保持存储过程在数据级别执行其余操作(您仍可以更新数量列),请使用表值参数,该参数将数据表作为参数传递给存储过程。

SQL:

CREATE PROCEDURE [PurchaseToys]
     @tblPurchaseOrders Toy_Purchase READONLY AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO Toy_Purchase(column1, column2, .. )
        SELECT 
            column1, column2,..  
        FROM @tblPurchaseOrders

        --Do what else you want to do here.. 
END

C#:

using (SqlConnection con = new SqlConnection(Connectionstring))
{
    using (SqlCommand cmd = new SqlCommand("PurchaseToys"))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Connection = con;

        cmd.Parameters.AddWithValue("@tblPurchaseOrders", dt); // dt -> data to be inserted

        con.Open();
        cmd.ExecuteNonQuery();
        con.Close();
    }
}

其他选项是遍历C#中的每个记录并调用存储过程。