2017-02-21 6 views
0

Это мой стол конструкции:Как добавить несколько строк в одну таблицу с хранимой процедурой в 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_Price из Cart таблицы будет принят и включен в Total_Quantity и Total_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 [email protected]) 

    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 разных игрушки, хранимая процедура должна вставить 2 строки в таблицу Toy_Purchase, а значение столбца Quantity в таблице Toy будет уменьшено для 2 разных игрушек.

Если я купил 4 разных игрушки, хранимая процедура должна вставить 4 строки в таблицу Toy_Purchase, а значение столбца Quantity в таблице игрушек будет уменьшено для 4 разных игрушек.

Как я могу убедиться, что несколько строк будут вставлены в таблицу Toy_Purchase, а значение столбца Quantity будет уменьшено для количества различных выбранных игрушек через хранимую процедуру в ADO.NET?

+0

[Плохие привычки пинать: использование JOIN в старом стиле] (http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style- joins.aspx) - стиль старого стиля *, разделенный запятыми * стиль таблицы был заменен синтаксисом * надлежащего * ANSI 'JOIN' в ANSI - ** 92 ** SQL Standard (** 25 лет ** назад) и его использование не рекомендуется –

ответ

1

Если вы хотите избежать вызова хранимой процедуры для каждой строки, у вас есть несколько вариантов, которые вы можете решить.

Вы можете использовать метод SQLBulkCopy из C#, с помощью которого вы можете передать datatable в качестве параметра в таблицу. Если вы все же хотите, чтобы хранимая процедура выполняла остальную операцию на уровне данных (вы все же можете обновить столбец количества), используйте параметры таблицы, которые передают таблицу данных в качестве параметра хранимой процедуры.

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# и вызов хранимой процедуры.

Смежные вопросы