为啥这个带参数的 sqlsrv 查询不起作用?

Posted

技术标签:

【中文标题】为啥这个带参数的 sqlsrv 查询不起作用?【英文标题】:Why does this sqlsrv query with parameters not work?为什么这个带参数的 sqlsrv 查询不起作用? 【发布时间】:2019-01-09 16:19:08 【问题描述】:

我的代码中有以下函数。

private function getFormsOfWords($search)

    $query = "SELECT display_term, source_term, occurrence FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL, ?)', 2057, 0, 0)";

    $stmt = sqlsrv_query($this->db, $query, array($search));

    if( $stmt === false ) 
        file_put_contents(LOG_DIR.'/search.txt', print_r(sqlsrv_errors(),true), FILE_APPEND);
        die();
    
    $highlight_words = array();
    while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) 
        $highlight_words[] = $row['display_term'];
    

    return $highlight_words;

问题是当我到达 sqlsrv_fetch_array 部分时,我没有得到任何结果。

调试器显示 $search 变量已填充并且确实到达了 sqlsrv_fetch_array 行。

我以完全相同的方式完成的所有其他查询在执行 sqlsrv_fetch_array 后都成功产生了结果。

我已经在数据库本身中测试了 $highlight_words_SQL 查询,并手动替换了参数,它工作正常。主要区别在于参数需要在手动执行时使用引号。我假设 sqlsrv_query 的 param 参数以可以处理此要求的方式进行处理,但我也尝试了以下查询,结果相同:

$query = "SELECT display_term, source_term, occurrence FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL, \"?\")', 2057, 0, 0)";

“search.txt”错误日志没有显示任何内容,任何其他 apache 或 php 日志也没有。

知道是什么原因造成的吗?

编辑:

我也尝试了以下排列:

$query = "SELECT display_term, source_term, occurrence 
            FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,' + ? + ')', 2057, 0, 0)";
//Syntax error near 'initialized' in the full-text search condition 'FORMSOF(INFLECTIONAL,security initialized)'.

$query = "SELECT display_term, source_term, occurrence 
            FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,' + \"?\" + ')', 2057, 0, 0)";
//Invalid column name '?'

$query = "SELECT display_term, source_term, occurrence 
            FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,\'' + \"?\" + '\')', 2057, 0, 0)";
//Incorrect syntax near '\'.

这个:

SELECT display_term, source_term, occurrence 
  FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL, '+'"security initialized"'+')', 2057, 0, 0)

或者这个:

SELECT display_term, source_term, occurrence 
  FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL, "security initialized")', 2057, 0, 0)

是目标,因为它们是在 SSMS 中工作的查询。

【问题讨论】:

参数不在引号内展开。 【参考方案1】:

查询中带引号的字符串内的参数不会被替换。您需要使用连接来构建字符串。

$query = "SELECT display_term, source_term, occurrence 
            FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,' + ? + ')', 2057, 0, 0)";

【讨论】:

我在尝试该查询时得到以下信息:全文搜索条件“FORMSOF(INFLECTIONAL,security initialized)”中“已初始化”附近的语法错误。【参考方案2】:

这个版本的查询有效:

$query = "SELECT display_term, source_term, occurrence 
            FROM sys.dm_fts_parser('FORMSOF(INFLECTIONAL,\"' + ? + '\")', 2057, 0, 0)";

【讨论】:

以上是关于为啥这个带参数的 sqlsrv 查询不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个简单的“INSERT INTO”查询不起作用

为啥这个 T-SQL 查询在 Synapse 中不起作用?

为啥这个使用 INNER JOIN 的 SQL DELETE 查询不起作用? [复制]

为啥速记参数名称在这个 Swift 闭包中不起作用?

为啥这个 IF NOT EXISTS 语句不起作用?

在 php 7.2 中启用 pdo_sqlsrv,不起作用