PHP SQLSRV - 参数化时全文查询不起作用

时间:2015-10-23 17:51:17

标签: php sql-server sqlsrv

当我通过PHP sqlsrv驱动程序运行以下查询时,没有错误发生,但也没有返回任何行...如果我摆脱了问号(应该是参数)并插入关键字,那么它只返回行细...

SELECT DISTINCT
  MAX(i.ID) AS ID,
  i.ItemLookupCode,
  MAX(i.DepartmentID) AS DepartmentID,
  MAX(i.CategoryID) AS CategoryID,
  MAX(i.Quantity) AS Quantity,
  MAX(CAST(i.Notes AS varchar(max))) AS Notes,
  MAX(CONVERT(varchar(30), i.Price, 1)) AS Price,
  MAX(i.SaleType) AS SaleType,
  MAX(i.SaleStartDate) AS SaleStartDate,
  MAX(i.SaleEndDate) AS SaleEndDate,
  MAX(CONVERT(varchar(30), i.SalePrice, 1)) AS SalePrice,
  MAX(i.PictureName) AS PictureName,
  MAX(n.SpoofStock) AS SpoofStock,
  MAX(n.PAM_Brand) AS Brand

FROM Item AS i

LEFT JOIN nitroasl_pamtable AS n
  ON i.ID = n.ItemID

WHERE CONTAINS(
  (i.ItemLookupCode, i.Notes, i.Description, i.ExtendedDescription),
  '? AND ?')

OR CONTAINS(
  (n.PAM_Brand, n.ManufacturerPartNumber, n.PAM_Keywords),
  '? AND ?')

AND ( i.WebItem = 1 AND i.Price > 0 )

GROUP BY i.ItemLookupCode

ORDER BY i.ItemLookupCode ASC

我已经验证我的参数数组是正确的......下面是我的脚本:

require LIBRARY_PATH . "/connect-db.php";

$tsql = "SELECT DISTINCT
          MAX(i.ID) AS ID,
          i.ItemLookupCode,
          MAX(i.DepartmentID) AS DepartmentID,
          MAX(i.CategoryID) AS CategoryID,
          MAX(i.Quantity) AS Quantity,
          MAX(CAST(i.Notes AS varchar(max))) AS Notes,
          MAX(CONVERT(varchar(30), i.Price, 1)) AS Price,
          MAX(i.SaleType) AS SaleType,
          MAX(i.SaleStartDate) AS SaleStartDate,
          MAX(i.SaleEndDate) AS SaleEndDate,
          MAX(CONVERT(varchar(30), i.SalePrice, 1)) AS SalePrice,
          MAX(i.PictureName) AS PictureName,
          MAX(n.SpoofStock) AS SpoofStock,
          MAX(n.PAM_Brand) AS Brand

        FROM Item AS i

        LEFT JOIN nitroasl_pamtable AS n
          ON i.ID = n.ItemID

        WHERE CONTAINS(
          (i.ItemLookupCode, i.Notes, i.Description, i.ExtendedDescription),
          '? AND ?')

        OR CONTAINS(
          (n.PAM_Brand, n.ManufacturerPartNumber, n.PAM_Keywords),
          '? AND ?')

        AND ( i.WebItem = 1 AND i.Price > 0 )

        GROUP BY i.ItemLookupCode

        ORDER BY i.ItemLookupCode ASC";

// Allows us to determine the number of rows returned
$cursorType = array('Scrollable' => SQLSRV_CURSOR_KEYSET);

$stmt = sqlsrv_query( $conn, $tsql, $params, $cursorType );

if ( !$stmt )
{
  die( FormatErrors( sqlsrv_errors() ) );
}

if( sqlsrv_has_rows( $stmt ) )
{
  while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC))
  {
    $results[] = $row;
  }
}

sqlsrv_free_stmt( $stmt );

require LIBRARY_PATH . "/disconnect-db.php";

对于上面的脚本,参数数组如下所示:

Array
(
  [0] => displayport
  [1] => hdmi
  [2] => displayport
  [3] => hdmi
)

请注意,我根据解析的关键字数量动态创建填充"?" AND "?"的字符串。我确认字符串是正确的,上面反映了它们会产生什么。

那么,这不是一个有效的参数化sqlsrv查询吗?

1 个答案:

答案 0 :(得分:2)

CONTAINS子句的第二个参数是你应该参数化的。

这部分:

WHERE CONTAINS(
  (i.ItemLookupCode, i.Notes, i.Description, i.ExtendedDescription),
  '"?" AND "?"')

OR CONTAINS(
  (n.PAM_Brand, n.ManufacturerPartNumber, n.PAM_Keywords),
  '"?" AND "?"')

应该写成:

WHERE CONTAINS(
  (i.ItemLookupCode, i.Notes, i.Description, i.ExtendedDescription),
  ?)

OR CONTAINS(
  (n.PAM_Brand, n.ManufacturerPartNumber, n.PAM_Keywords),
  ?)

并假设您的$params看起来像这样:

 $params = ['a', 'b', 'c', 'd']

它应该看起来像:

 $params = [
   '"a" AND "b"', 
   '"c" AND "d"'
 ]