Проблемы ASP.NET SQL и помощь по коду - PullRequest
1 голос
/ 06 декабря 2010

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

Я вчера отправил вопрос о присвоении результатакоманда SQL для переменной, но, похоже, ничего не работает, возможно, из-за написанного мною кода, если есть решение для этого, я был бы очень признателен.

Также есть способ упростить команды SQL, которые яКажется, я делаю довольно много

Я знаю об уязвимости для атак с использованием SQL-инъекций, это всего лишь проект Uni, и я сомневаюсь, что лектор даже знает о них!Тем не менее, я разберусь с этим, как только у меня заработает базовая функциональность:)

string CurrentUser="";
if (User.Identity.IsAuthenticated) {
    CurrentUser = Membership.GetUser(HttpContext.Current.User.Identity.Name).ProviderUserKey.ToString(); //Get the current user
}

//Insert the current user into the DB
BasketPage.InsertCommand = "INSERT INTO tblBasket(UserID, CreatedDate) VALUES ('" + CurrentUser + "'), CONVERT (DATETIME, '2010-11-20 00:00:00', 102))"; 

//Select the Basket ID for this user which is an auto increment hence why I inserted the user first
BasketPage.SelectCommand = "SELECT BasketID FROM tblBasket WHERE (UserID = '" + CurrentUser + "')"; 

var basketID= //Result of the previous select command

if (Session["CartSess"] != null) {
    List<BasketClass> cart = (List<BasketClass>)Session["CartSess"];

    foreach (BasketClass BookID in (List<BasketClass>)Session["CartSess"]) {
        BasketPage.InsertCommand = "INSERT INTO tblBasketDetails(BasketID, BookID) VALUES (" + 
                                   basketID + "," + BookID + ")"; //Inserts each book into the DB and the Basket ID
        BasketPage.Insert();
    }
}

//Outputs the Basket for the current user
BasketPage.SelectCommand = "SELECT tblBasket.UserID, tblBasket.BasketID, tblBooks.Title, tblBasketDetails.Quantity " +
                           "FROM tblBasket " +
                           "INNER JOIN tblBasketDetails ON tblBasket.BasketID = tblBasketDetails.BasketID " + 
                           "INNER JOIN tblBooks ON tblBasketDetails.BookID = tblBooks.BookID " + 
                           "WHERE (tblBasket.UserID = '" + CurrentUser + "')"; 

Ответы [ 2 ]

2 голосов
/ 06 декабря 2010

Я бы посоветовал вам поместить свой код SQL в хранимые процедуры, а не писать их в виде строки.Этот вид кодирования становится трудно поддерживать очень быстро.И, конечно, как вы упоминаете, существуют атаки с использованием SQL-инъекций.

Я опубликовал примерный код SQL, специфичный для SQL Server.Вам может потребоваться внести некоторые изменения для MySQL или некоторых других СУБД).

Например

На БД.

CREATE PROCEDURE BasketInsert
    @UserId INT
AS
BEGIN
    INSERT INTO tblBasket
    (UserId, CreatedDate)
    VALUES
    (
        @UserId,
        GetDate() -- built in SQL function to return the current datetime.
    )

SELECT Scope_Identity() AS BasketId -- returns latest basketId ie. the one you have just inserted.

END



CREATE PROCEDURE BasketDetailInsert
    @BasketId INT,
    @BookId INT
AS
BEGIN
    INSERT INTO
        tblBasketDetails(BasketID, BookID) 
    VALUES
        (
            @BasketId,
            @BookId
        )
END




CREATE PROCEDURE BasketSelect
    @CurrentUserId INT
AS
BEGIN
    SELECT
        tblBasket.UserID, 
        tblBasket.BasketID,
        tblBooks.Title,
        tblBasketDetails.Quantity 
    FROM tblBasket 
    INNER JOIN tblBasketDetails ON tblBasket.BasketID = tblBasketDetails.BasketID
    INNER JOIN tblBooks ON tblBasketDetails.BookID = tblBooks.BookID
    WHERE (tblBasket.UserID = @CurrentUserId
END

И изменить свой код на стороне сервера для использованияэти хранимые процедуры вместо «произвольного SQL».

HTH>

[Кстати, я был бы очень удивлен, если бы ваши преподаватели не знали о SQL-инъекции.]

РЕДАКТИРОВАТЬ:

Извините, забыл упомянуть - функция Scope_Identity () зависит от SQL Server.Он просто возвращает самый последний идентификатор из рассматриваемой таблицы.Вы можете либо получить его, как я сделал, используя инструкцию SELECT, либо включить параметр Output в свою процедуру, назначить его с помощью Scope_identity () и получить значение на стороне сервера.Эта статья http://www.4guysfromrolla.com/articles/062905-1.aspx может помочь.

2 голосов
/ 06 декабря 2010

В строке:

BasketPage.InsertCommand = "INSERT INTO tblBasket(UserID, CreatedDate) VALUES ('" + CurrentUser + "'), CONVERT (DATETIME, '2010-11-20 00:00:00', 102))"; //Insert the current user into the DB

Подставляя 'SomeValue' для вашей переменной CurrentUser, ваш SQL будет:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue'), CONVERT (DATETIME, '2010-11-20 00:00:00', 102))

Попробуйте запустить это в окне SQL.В SQL Server вы получите:

В операторе INSERT больше столбцов, чем значений, указанных в предложении VALUES.Количество значений в предложении VALUES должно соответствовать количеству столбцов, указанному в операторе INSERT.

Ваша проблема с первой скобкой clsing в строке VALUES.Код должен быть:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue', CONVERT (DATETIME, '2010-11-20 00:00:00', 102))

В качестве общего совета попробуйте протестировать свои запросы автономно, прежде чем запускать их как часть своего кода.

Если отбросить упомянутые вами проблемы с SQL-инъекцией, это еще одна причина для переноса всего вашего кода в хранимую процедуру и вызова его с параметрами из вашего кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...