【问题标题】:ODBC prepared statements in PHPPHP 中的 ODBC 准备语句
【发布时间】:2025-11-29 09:30:01
【问题描述】:

我正在尝试在 PHP 中使用 odbc_prepare 和 odbc_execute,如下所示:

$pstmt=odbc_prepare($odb_con,"select * from configured where param_name='?'");
$res=odbc_execute($pstmt,array('version'));
var_dump($res);  //bool(true)
$row = odbc_fetch_array($pstmt);
var_dump($row);  //bool(false)

第一个 var_dump 返回 true,因此执行成功,但没有返回任何行。 param_name = 'version' 确实存在一行。为什么没有返回行?

为了让事情变得有趣,我使用准备好的插入在 php 中运行了另一个非常简单的示例。

$pstmt=odbc_prepare($odb_con,"insert into tmp1 values(?,'?')");

这一行本身就向数据库中插入了一行!!这肯定是错的吗?输入的数据是 col 1 = 空白,col 2 = ?

任何关于从哪里开始解决此问题的建议将不胜感激,谢谢。

编辑:这是在 PHP 5.2.8 中

【问题讨论】:

  • odbc_num_rows($res); 返回什么?我想确认查询确实返回了非空结果。 odbc_fetch_array() 可能返回 false,因为结果集中没有行。另外,您的 PHP 错误日志中是否出现任何错误消息?
  • 您尝试过我建议的解决方案吗?请提供反馈
  • 不幸的是,新的回复将不得不等到我有时间再次查看这个特殊问题。我现在有其他任务。
  • 只是为了更新这个问题:我从来没有找到解决方案。我只需要没有准备好的陈述。我怀疑它是安装在我正在开发的系统上的 ODBC 驱动程序。不幸的是,这不能很快改变。
  • 这是一篇旧帖子,但是如果您想循环选择语句的结果,您会怎么做?我正在尝试做类似的事情

标签: php odbc prepared-statement


【解决方案1】:

尝试从查询字符串中删除单引号并将它们添加到参数值本身:

$pstmt=odbc_prepare($odb_con,"select * from configured where param_name=?");
$res=odbc_execute($pstmt,array(" 'version'"));
var_dump($res);  //bool(true)
$row = odbc_fetch_array($pstmt);
var_dump($row);  //bool(false)

参数值开头的单个空格字符非常重要——如果没有空格,它将把变量当作文件的路径。

来自http://www.php.net/manual/en/function.odbc-execute.php

如果你想存储一个字符串 实际上以单人开头和结尾 引号,您必须添加空格或其他 非单引号字符 参数的开头或结尾, 这将阻止参数 被当作​​文件名。

【讨论】:

  • 试过了,但它认为参数是一个列。
  • 查看odbc_execute上的文档...它仅在成功执行查询时返回布尔值,true(无论该行是否存在或not) 如果查询失败,则返回 false。 AND odbc_exec 返回一个资源。
【解决方案2】:

当我读到这一段时

parameter_array 中以单引号开头和结尾的任何参数都将被视为要读取的文件名,并将其作为相应占位符的数据发送到数据库服务器。

如果您希望存储一个实际以单引号开头和结尾的字符串,您必须在参数的开头或结尾添加空格或其他非单引号字符,这将防止参数被视为一个文件名。如果这不是一个选项,那么您必须使用另一种机制来存储字符串,例如直接使用 odbc_exec()) 执行查询。

在我看来,没有必要将单引号 ' 添加到字符串中,前提是您确实希望将引号作为文本在 DB 中

因此,如果我只想插入文本,没有单引号,我会写这样的东西......

从 odbc-prepare 看这个例子

http://www.php.net/manual/en/function.odbc-prepare.php

Use this example for IBM DB/2:

$q = "update TABLE set PASS=? where NAME=?";
$res = odbc_prepare ($con, $q);

$a = "secret"; $b="user";
$exc = odbc_execute($res, array($a, $b));

这将导致以下语句

$pstmt=odbc_prepare($odb_con,"select * from configured where param_name=?");

$name = "version";
$params = array($name);

$res=odbc_execute($pstmt,$params);
var_dump($res);  //bool(true)

$row = odbc_fetch_array($pstmt);
var_dump($row);  //bool(false)

看到我不仅删除了 params 数组中值的qoutes,还删除了SQL 语句中的qoutes

如果正确,请提供反馈

【讨论】:

    【解决方案3】:

    您不应在准备好的语句中将变量括在引号中:

    $pstmt=odbc_prepare($odb_con,"select * from configured where param_name=?"); $res=odbc_execute($pstmt,array(" 'version'"));

    应该是:

    $pstmt=odbc_prepare($odb_con,"select * from configured where param_name=?"); $res=odbc_execute($pstmt,array("version"));

    问号表示参数占位符,传递的值表示一个未转义的、未封闭的值,SQL 解释器将对其进行正确转义。

    【讨论】:

      【解决方案4】:

      编辑:

      呸,别理我,误读php.net

      odbc_fetch_array 接受 odbc_execute 的结果作为它的参数,您似乎在传递准备好的语句。

      【讨论】:

      【解决方案5】:

      您使用的是什么 DBMS?单独的插入准备语句似乎是针对数据库执行而不是准备的这一事实表明 php 的实现不佳(不太可能)或 DBMS 不支持准备好的 sql。如果是后者,那么他们支持没有功能的命令的方式可能只是执行导致您获得结果的语句。如果 DBMS 确实 支持准备好的语句并且 php 实现正确处理它,那么执行插入时会出现某种问题,这也需要进行一些调查。

      【讨论】:

      • 我忘了问你用的是什么 php 解释器;如果有任何问题可能导致这种情况,我会好好看看,因为似乎函数调用是问题而不是你的代码
      • Linux fedora 上的 PHP 5.2.8。不完全确定你的意思是哪个 php 解释器
      【解决方案6】:

      你试过用双引号吗?即

      $res=odbc_execute($pstmt,array("version"));
      

      【讨论】: