我有一个参数化查询,如下所示:
SELECT title, html, shortname FROM dbo.Videos
WHERE Topic_ID = ? AND dbo.gradeLevelCheck(?, Grade_Lower, Grade_Upper) = 1
ORDER BY shortname ASC
当我从ASP运行它时,我收到一个错误,内容如下:
Incorrect syntax near the keyword 'from'
参数56
和1
(因此没有空值)。存储的函数dbo.gradeLevelCheck
如下所示:
ALTER FUNCTION [dbo].[gradeLevelCheck]
(
@value int,
@lower int,
@upper int
)
RETURNS int
AS
BEGIN
DECLARE @result int;
IF (@lower IS NULL OR @lower <= @value) AND (@upper IS NULL OR @upper >= @value)
SET @result = 1;
ELSE
SET @result = 0;
RETURN @result;
END
如果我使用硬编码到查询中的参数提交它,它工作正常。如果我删除 ORDER BY 子句,它也可以正常工作。但我无法让它以这种形式工作。谁能帮我弄清楚为什么?
编辑:这里有一些额外的细节。该应用程序是用带有 JScript 的经典 ASP 编写的。连接建立方式如下:
var conn = Server.CreateObject('ADODB.Connection');
var connectionString =
'Provider=SQLOLEDB;' +
'Data Source=' + Settings.dbServer + ';' +
'Initial Catalog=' + Settings.dbCatalog + ';' +
'User Id=' + Settings.dbUser + ';' +
'Password=' + Settings.dbPass + ';' +
'Connect Timeout=15;';
conn.Open(connectionString, conn);
用于提交查询的代码如下所示:
DB.query = function(query) {
...
var cmd = Server.CreateObject("ADODB.Command");
cmd.activeConnection = conn;
cmd.commandText = query;
for (var i = 1; i < arguments.length; i++) {
cmd.Parameters(i-1).value = arguments[i];
}
return cmd.Execute();
...
}
(此处,参数 1
和 56
作为附加参数传递给 DB.query
。
"关键字'from'附近的语法不正确"是您在通过连接字符串并忘记单词之间的一些空格来构建查询时遇到的经典错误。我想这里第一行的末尾之间缺少一个空格(...视频)和第二行的开头(哪里...
我看到了查询文本,也看到了函数如何接受该文本,但我仍然缺少一件事来准确诊断这一点:如何将查询文本放入代码中?
我问,因为我有一种感觉,你有这样的东西:
query = "SELECT title, html, shortname FROM dbo.Videos"
+ "WHERE TopicID = ? .... ";
请注意创建该字符串变量时会发生什么。它将看起来像这样:
从 dbo 中选择标题、html、短名称。视频其中主题 ID = ?....
请注意,dbo.Videos
和 WHERE
之间没有任何内容。您没有在两行之间包含任何空格。原始代码中的换行符不是任一字符串文本的一部分。你需要这样的东西:
query = "SELECT title, html, shortname FROM dbo.Videos"
+ " WHERE TopicID = ? .... ";
请注意为 WHERE
关键字添加空格。
另一个建议是删除dbo.
部分,仅使用 Videos
作为表名。我知道你所拥有的应该是有效的语法,但一定发生了一些不寻常的事情,否则我们已经解决了它。要尝试的另一件事是在表和列名称周围放置括号。
我已经找到了问题所在。这是我的假设:
似乎通常 ADO 能够根据查询的结构推断参数的类型。但是,在这种情况下,预准备语句的参数之一是函数 dbo.gradeLevelCheck
的参数,这会导致类型推断失败。(据推测,ADO 不理解存储函数或其他东西,因此它不知道如何检查参数应该是什么类型。由于它无法确定类型,因此查询无效。
我仍然不知道为什么如果删除ORDER BY
子句,这个查询似乎有效,但很明显我无论如何都必须更改代码。