2

我有一个看起来像这样的参数化查询:

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'

参数是561(所以没有空值)。存储的函数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 的 Classic 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();
    ...
    }

(这里,参数156作为附加参数传递给DB.query。)

4

3 回答 3

6

“关键字'from'附近的语法不正确”是您在通过连接字符串并忘记单词之间的一些空格来构建查询时遇到的经典错误。我猜这里第一行的结尾(...视频)和第二行的开头(WHERE ...)之间缺少一个空格

于 2013-01-30T05:26:09.733 回答
2

我看到了查询文本,并且看到了函数如何接受该文本,但我仍然缺少一件事来准确诊断:如何将查询文本放入代码中?

我问,因为我有一种感觉,你有这样的事情:

query = "SELECT title, html, shortname FROM dbo.Videos"
      + "WHERE TopicID = ? .... ";

请注意创建该字符串变量时会发生什么。它看起来像这样:

从 dbo.VideosWHERE TopicID = 选择标题、html、短名称 ……

dbo.Videos请注意,和之间根本没有任何东西WHERE。您没有在两行之间包含任何空格。原始代码中的换行符不是任一字符串文字的一部分。你需要这样的东西:

query = "SELECT title, html, shortname FROM dbo.Videos"
     + " WHERE TopicID = ? .... ";

请注意为WHERE关键字添加了一个空格。


另一个建议是删除该dbo.部分并仅Videos用于表名。我知道你所拥有的应该是有效的语法,但一定有一些不寻常的事情发生,否则我们已经解决了。要尝试的另一件事是在表格和列名周围放置方括号。

于 2013-01-30T05:19:14.553 回答
1

我相信我已经找到了问题所在。这是我的假设:

似乎通常 ADO 能够根据查询的结构推断参数的类型。但是,在这种情况下,prepared statement 的参数之一是 function 的参数dbo.gradeLevelCheck,这会导致类型推断失败。(大概,ADO 不理解存储函数什么的,所以它不知道如何检查参数应该是什么类型。)因为它无法确定类型,所以查询是无效的。

我仍然不知道为什么如果ORDER BY删除该子句,这个查询似乎可以工作,但很明显我无论如何都必须更改代码。

于 2013-02-01T19:59:30.003 回答