C# ASP.NET SQL问题和代码帮助

C# ASP.NET SQL问题和代码帮助,c#,asp.net,sql,C#,Asp.net,Sql,我编写了下面的代码,用于将产品添加到一个篮子中,然后输出它们,以及向服务器发出多个请求以插入和选择数据 我昨天发布了一个关于将SQL命令的结果分配给变量的问题,但似乎没有任何效果,可能是由于我编写的代码,如果有解决方案,我将非常感激 此外,还有什么方法可以简化我似乎正在制作的许多SQL命令 我知道SQL注入攻击的漏洞,这只是一个Uni项目,我怀疑讲师是否知道!不过,一旦基本功能正常工作,我将对这些问题进行分类: string CurrentUser=""; if (User.Identity.I

我编写了下面的代码,用于将产品添加到一个篮子中,然后输出它们,以及向服务器发出多个请求以插入和选择数据

我昨天发布了一个关于将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 + "')"; 
在线:

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
将CurrentUser变量替换为“SomeValue”,则SQL为:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue'), CONVERT (DATETIME, '2010-11-20 00:00:00', 102))
尝试在SQL窗口中运行它。在SQL Server中,您将获得:

插入中有更多列 语句中指定的值 价值条款。中的值数 VALUES子句必须与 中指定的列数 插入语句

您的问题在于值行上的第一个clsing括号。代码应为:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue', CONVERT (DATETIME, '2010-11-20 00:00:00', 102))
作为一般建议,在将查询作为代码的一部分运行之前,请尝试单独测试查询

抛开您提到的SQL注入问题不谈,这是将所有代码移动到存储过程并使用代码中的参数调用它的另一个原因

在线:

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
将CurrentUser变量替换为“SomeValue”,则SQL为:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue'), CONVERT (DATETIME, '2010-11-20 00:00:00', 102))
尝试在SQL窗口中运行它。在SQL Server中,您将获得:

插入中有更多列 语句中指定的值 价值条款。中的值数 VALUES子句必须与 中指定的列数 插入语句

您的问题在于值行上的第一个clsing括号。代码应为:

INSERT INTO tblBasket(UserID, CreatedDate) 
VALUES ('SomeValue', CONVERT (DATETIME, '2010-11-20 00:00:00', 102))
作为一般建议,在将查询作为代码的一部分运行之前,请尝试单独测试查询


抛开您提到的SQL注入问题不谈,这是将所有代码移动到存储过程并使用代码中的参数调用它的另一个原因

我建议您将SQL代码放入存储过程中,而不是像这样内联编写它们。这种编码很快就变得难以维护。当然,正如您所提到的,存在SQL注入攻击

我已经发布了一些特定于SQLServer的样板SQL代码。您可能需要对MySQL或其他RDBMS进行一些更改

例如

在数据库上

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
并修改服务器端代码以使用这些存储过程,而不是“freehand SQL”

HTH>

[顺便提一下,如果您的导师不知道SQL注入,我会非常惊讶。]

编辑:


抱歉,忘了提及-Scope_Identity函数是特定于SQL Server的。它只返回相关表中最近的ID。您可以像我使用SELECT语句一样获取它,也可以在过程中包含一个输出参数,通过Scope_identity分配它,并在服务器端获取值。本文可能会有所帮助。

我建议您将SQL代码放入存储过程中,而不是像这样内联编写它们。这种编码很快就变得难以维护。当然,正如您所提到的,存在SQL注入攻击

我已经发布了一些特定于SQLServer的样板SQL代码。您可能需要对MySQL或其他RDBMS进行一些更改

例如

在数据库上

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
并修改服务器端代码以使用这些存储过程,而不是“freehand SQL”

HTH>

[顺便提一下,如果您的导师不知道SQL注入,我会非常惊讶。]

编辑:


抱歉,忘了提及-Scope_Identity函数是特定于SQL Server的。它只返回相关表中最近的ID。您可以像我使用SELECT语句一样获取它,也可以在过程中包含一个输出参数,通过Scope_identity分配它,并在服务器端获取值。本文可能会有所帮助。

请不要将整个SQL语句写在一行上。阅读起来非常困难,但似乎什么都不管用。到底是什么?你能提供更多关于它如何工作的信息吗?我的问题是将SQL命令的结果分配给变量,我想将BasketID的结果分配给变量请不要将整个SQL语句写在一行上。阅读起来非常困难,但似乎什么都不管用。到底是什么?你能提供更多关于它如何工作的信息吗?我的问题是将SQL命令的结果分配给变量,我想将BasketID的结果分配给变量variable@JamesWiseman-你对语法有点一丝不苟-那个编辑似乎应该在english.stackexchange上继续
.com,-事实上,我想你会发现这是“语法”,而不是“语法”-哈哈哈!我有罪+1对于更迂腐的说法:-并不是说我通常喜欢这种东西,而是从你上面的帖子来看,你是一个如此固执的人:>作为一个一般性的建议。。。我想你会找到它的“建议”-Touché和+1表示[sic]。依我的拙见,你今天看的还不够多。哈哈。我不得不克制自己,不让自己在你使用上述句子中的撇号>'。。。够了。。哦,该死的,太晚了。也许是时候去english.stackexchange.com,惹恼更多的美国人了-@詹姆斯怀斯曼——你对语法有点挑剔——这篇编辑文章似乎应该在english.stackexchange.com上继续发表-事实上,我想你会发现这是“语法”,而不是“语法”-哈哈哈!我有罪+1对于更迂腐的说法:-并不是说我通常喜欢这种东西,而是从你上面的帖子来看,你是一个如此固执的人:>作为一个一般性的建议。。。我想你会找到它的“建议”-Touché和+1表示[sic]。依我的拙见,你今天看的还不够多。哈哈。我不得不克制自己,不让自己在你使用上述句子中的撇号>'。。。够了。。哦,该死的,太晚了。也许是时候去english.stackexchange.com,惹恼更多的美国人了-