【问题标题】:PDO and Firebird prepared SELECT query with LIKE is not workingPDO 和 Firebird 使用 LIKE 准备的 SELECT 查询不起作用
【发布时间】:2021-04-07 20:38:15
【问题描述】:

我正在尝试在 Firebird 数据库中使用 LIKE '%txt%' 执行查询,我使用带有 PDO 的 PHP 并且连接正常,我只是没有得到结果(回显返回 [])使用此代码:

header('Content-type: text/plain; charset=ISO-8859-1');

$host = 'firebird:dbname=192.x.x.x:/usr/interbase/test.gdb';
$username = 'test';
$password = 'test';

try{
  $db = new PDO($host, $username, $password);
  $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
  echo "Error: " . $e->getMessage();
}

$txt = "%Oll%";

$sql = "SELECT PRV_CODIGO id, PRV_RAZSOC text ";
$sql .= "FROM T_MYTABLE ";
$sql .= "WHERE PRV_RUT LIKE ':txt' OR PRV_RAZSOC LIKE ':txt'";

try{
  $select = $db->prepare($sql);
  $select->bindValue(":txt",$txt,PDO::PARAM_STR);
  $select->execute();
  $result = $select->fetchAll(PDO::FETCH_ASSOC);
  //var_dump($select);
  echo json_encode($result);
}catch (PDOException $e) {
  echo $e->getMessage();
}

我已经测试过这个东西:

如果我取消注释该 var_dump,它会在 Web 浏览器中显示以下内容:

object(PDOStatement)#2 (1) {
  ["queryString"]=>
  string(106) "SELECT PRV_CODIGO id, PRV_RAZSOC text FROM T_MYTABLE WHERE PRV_RUT LIKE ':txt' OR PRV_RAZSOC LIKE ':txt'"
}

您可以看到字符串保持 ':txt' 不变。

如果我将变量直接放在查询中,没有准备好的语句,像这样:

$sql = "SELECT PRV_CODIGO id, PRV_RAZSOC text ";
$sql .= "FROM T_MYTABLE ";
$sql .= "WHERE PRV_RUT LIKE '$txt' OR PRV_RAZSOC LIKE '$txt'";

它运行良好,它带来了结果,并且 var_dump 显示以下内容:

object(PDOStatement)#2 (1) {
  ["queryString"]=>
  string(108) "SELECT PRV_CODIGO id, PRV_RAZSOC text FROM T_MYTABLE WHERE PRV_RUT LIKE '%Oll%' OR PRV_RAZSOC LIKE '%Oll%'"
}

因为字符串现在得到 $txt 值而不是保留 ':txt' 才有效。当然我不能把那个变量放在那里,因为我正试图用准备好的语句来做到这一点。

所以我需要知道发生了什么,我从来没有遇到过这种 MySQL 问题。

【问题讨论】:

  • 通常,绑定变量没有引号 - LIKE :txt
  • @NigelRen 没错,但如果我删除引号,Firebird 会抛出错误 804。在使用 MySQL 时,我从不使用这些引号。
  • 我怀疑你的问题是当你取消引用参数时(你应该这样做,否则它们只会被视为字符串),你遇到了火鸟驱动程序不支持使用相同的问题参数名称不止一次。尝试WHERE PRV_RUT LIKE :txt OR PRV_RAZSOC LIKE :txt2 并将$txt 绑定到:txt:txt2
  • Firebird 没有命名参数;我没有用 PHP 编程,所以我不知道 PDO 是否翻译这些,但否则你将不得不使用位置参数,即?。如果您像现在一样使用':txt',那么您只是使用值为:txt 的字符串文字。
  • 另外,Firebird 中不存在错误 804,也许您的意思是 -804 至少涵盖了 7 个不同的错误,所以您最好提供实际的错误信息。

标签: php pdo firebird firebird2.5


【解决方案1】:

当您使用 ':txt' 时,您没有指定参数,而是指定长度为 4 的字符串文字,并指定字符 :txt 作为其值.

Firebird 本身不支持命名参数,但快速查看 PDO 文档表明它会为您执行转换。那么解决方案是使用:txt(没有引号!),或位置参数:?

所以要么:

SELECT PRV_CODIGO id, PRV_RAZSOC text 
FROM T_MYTABLE 
WHERE PRV_RUT LIKE :txt OR PRV_RAZSOC LIKE :txt

或者:

SELECT PRV_CODIGO id, PRV_RAZSOC text 
FROM T_MYTABLE 
WHERE PRV_RUT LIKE ? OR PRV_RAZSOC LIKE ?

在最后一种情况下,您需要为每个参数绑定从 1 开始的索引:

$select->bindValue(1, $txt, PDO::PARAM_STR);
$select->bindValue(2, $txt, PDO::PARAM_STR);

【讨论】:

    猜你喜欢
    • 2013-06-15
    • 1970-01-01
    • 2014-04-04
    • 2010-12-19
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多