我正在从动态生成的(虽然经过严格消毒)SQL查询转换为参数化SQL,并且我遇到了变量名称的问题。
我正在使用经典ASP,用jScript编码。
以下代码采用评级值(1-5)并将其放入数据库中。首先,它删除该对象的所有用户先前评级,然后将新评级写入数据库。该函数已经收到,我已经解析了Rating变量(一个TinyInt)。 UserID和PgID值都是整数,也已发送。
我已经通过将@UserID,@ PigID和@Rating替换为问号,删除DECLARE,并将Append / CreateParemeter行按正确的顺序放置(每个一个?)来实现这一点。它确实涉及多次调用Append / CreateParameter行(对于每个UserID实例一次),这只是草率。
这段代码不会抛出任何错误,但它不会向数据库写入任何内容。 无论如何,我不知道为什么它会适用于问号(和重复参数),但不适用于声明的变量。
在Classic ASP jScript中使用参数化SQL时,如何使用命名变量?
如果无法做到,有没有办法避免每次我需要重复相同的Append / CreateParamenter行,例如UserID?
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时需要一些简单的东西。在我把它放到这里之前,它还被进一步简化(并再次测试)。一旦我开始工作,我就可以构建更复杂的查询。是的,我会编写存储过程,但是在所有工作完成之后会出现。
答案 0 :(得分:4)
如果您想避免重复,可以继续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);"
答案 1 :(得分:2)
使用adCmdText时,您必须使用?
占位符声明参数。添加参数时,ADO会根据您添加的顺序确定参数序列。
但是,一旦将其转换为存储过程,就可以按照您的尝试使用命名参数,顺序无关紧要。但是您必须将查询移动到存储过程以获得所需的结果。
有关详细信息,请参阅此MSDN article。
答案 2 :(得分:0)
您使用的是ADO提供程序,而不是SQL Server提供程序。
参数的ADO参数化查询语法为?
,而不是名称。