【问题标题】:Using variables in Classic ASP parameterized SQL在经典 ASP 参数化 SQL 中使用变量
【发布时间】:2011-06-16 19:10:58
【问题描述】:

我正在从动态生成(尽管经过严格清理)的 SQL 查询过渡到参数化 SQL,但我在变量名方面遇到了一些问题。

我使用的是经典 ASP,用 jScript 编码。

下面的代码获取一个评分值 (1-5) 并将其放入数据库中。首先,它会删除用户之前对该对象的所有评分,然后将新评分写入数据库。该函数已经收到并且我已经解析了 Rating 变量(一个 TinyInt)。 UserID 和 PgID 值(均为整数)也已发送。

我已经通过用问号替换 @UserID、@PgID 和 @Rating、删除 DECLARE 并将 Append/CreateParemeter 行以正确的顺序放置(每个一个?)来完成这项工作。但是,它确实涉及多次调用 Append/CreateParameter 行(每个 UserID 实例一次),这只是草率。

这段代码不会抛出任何错误,但不会向数据库写入任何内容。 无论如何,我不知道为什么它可以与问号(和重复的参数)一起使用,但不能与声明的变量一起使用。

在 Classic ASP jScript 中使用参数化 SQL 时如何使用命名变量?

如果没有办法,有没有办法避免每次我需要时都重复相同的 Append/CreateParamenter 行,例如用户 ID?

var sqlReview = "DECLARE @UserID AS Int, @PgID AS Int, @Rating AS TinyInt;"
sqlReview += "DELETE FROM PGrating WHERE (UserID = @UserID) AND (PgID = @PgID);"
sqlReview += "INSERT INTO PGrating (InsertDate, PgID, UserID, Rating) VALUES (GETDATE(), @PgID, @UserID, @Rating);"

var thisConnection = Server.CreateObject("ADODB.Connection");
thisConnection.connectionString = connectString;
thisConnection.Open();

var thisCommand = Server.CreateObject("ADODB.Command");
thisCommand.ActiveConnection = thisConnection;
thisCommand.CommandText = sqlReview;
thisCommand.CommandType = adCmdText;
thisCommand.Parameters.Append(thisCommand.CreateParameter("@UserID", adSmallInt, adParamInput, 2, UserID));
thisCommand.Parameters.Append(thisCommand.CreateParameter("@PgID", adInteger, adParamInput, 4, PgID));
thisCommand.Parameters.Append(thisCommand.CreateParameter("@Rating", adTinyInt, adParamInput, 1, Rating));
var rs = thisCommand.Execute();
thisCommand = null;
thisConnection = null;

我知道可能有更简单的方法可以将评级放入数据库,但创建这个示例主要是因为它很简单,而且我在学习如何使用参数化 SQL 时需要一些简单的东西。在我把它放在这里之前,它也被进一步简化(并再次测试)。一旦我得到这个工作,我就可以构建更复杂的查询。是的,我会写存储过程,但那是在一切正常之后。

【问题讨论】:

  • 在经典 ASP jScript 中创建参数化 SQL 调用时如何使用命名变量? (现在添加到上面的问题中)......如果没有办法,有没有办法避免每次我需要时都必须追加/创建参数,例如用户 ID?

标签: sql parameters asp-classic ado declare


【解决方案1】:

如果你想避免重复,你可以继续DECLARE你的变量并设置一次它们的值:

var sqlReview = "DECLARE @UserID AS Int = ?, @PgID AS Int = ?, @Rating AS TinyInt = ?;"
sqlReview += "DELETE FROM PGrating WHERE (UserID = @UserID) AND (PgID = @PgID);"
sqlReview += "INSERT INTO PGrating (InsertDate, PgID, UserID, Rating) VALUES (GETDATE(), @PgID, @UserID, @Rating);"

以上假设 SQL Server 2008 或更高版本。在较低版本上,您需要单独的一行进行分配:

var sqlReview = "DECLARE @UserID AS Int, @PgID AS Int, @Rating AS TinyInt;"
sqlReview += "SELECT @UserID = ?, @PgID = ?, @Rating = ?;"
sqlReview += "DELETE FROM PGrating WHERE (UserID = @UserID) AND (PgID = @PgID);"
sqlReview += "INSERT INTO PGrating (InsertDate, PgID, UserID, Rating) VALUES (GETDATE(), @PgID, @UserID, @Rating);"

【讨论】:

  • 我没有足够的“声誉”来投票赞成,但如果可以的话。太棒了。正是我要找的东西,谢谢!
  • 这似乎是一个好的开始,但并不完整。由于此示例与问题中的示例不同,这些变量引用如何绑定到 SQL 语句?如果这个答案包含一个完整的例子,那就太好了。
【解决方案2】:

使用 adCmdText 时,您必须使用 ? 占位符声明您的参数。添加参数时,ADO会根据你添加参数的顺序来确定参数的顺序。

但是,一旦将其转换为存储过程,就可以像尝试那样使用命名参数,并且顺序无关紧要。但是您必须将查询移动到存储过程中才能获得所需的结果。

请参阅此MSDN article 了解更多信息。

【讨论】:

    【解决方案3】:

    您使用的是 ADO 提供程序,而不是 SQL Server 提供程序。

    ADO 参数化查询语法是 ? 的参数,而不是名称。

    【讨论】:

    • 我不确定你在说什么。是否有不同类型的连接对象允许我使用命名变量?
    猜你喜欢
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多