You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP中odbc_execute配合odbc_fetch_row无返回值问题排查及解决

问题描述

我在类中编写了如下预处理语句:

function reader($ser)
{
    $pstmt=odbc_prepare($this->conn,'SELECT TOP 1 "name"
    FROM '.$this->table.' WHERE 
    "surname" LIKE ? ');        
    return odbc_execute($pstmt,array("$ser"));  
}

该函数通过POST获取参数$ser,示例值为:

$ser=' \'3221252\'';

调用方式为:

$serTab=$product->reader($ser);

但使用以下代码无法获取返回值(改用odbc_exec可正常工作):

while(odbc_fetch_row($serTab)) 
{ 
    for($i=1;$i<=odbc_num_fields($serTab);$i++) 
    {
        echo odbc_result($serTab,$i);                       
    } 
}

请问为何使用odbc_execute时无返回值?如何修复?是否有这些函数的替代方案?
另外,因出现错误「Conversion of parameter/column (5) from data type NVARCHAR to ASCII failed」,无法使用PDO;且我无数据库修改权限,DBMS为SAP Hana。


问题分析与解决方案

为什么odbc_execute无返回值?

odbc_execute()的返回值是布尔值(成功返回true,失败返回false),而非结果集资源。你将它的返回值赋值给$serTab,后续调用odbc_fetch_row()时自然无法处理——因为这个函数需要的是odbc_prepare()返回的预处理语句资源,或是odbc_exec()返回的结果集资源,而非布尔值。

而odbc_exec()会直接执行SQL并返回结果集资源,所以能正常遍历。

修复方法

修改reader()函数,返回预处理语句资源$pstmt,而非odbc_execute()的返回值。调用时先执行odbc_execute(),再用返回的资源处理结果集:

修改后的reader()函数

function reader($ser)
{
    $pstmt=odbc_prepare($this->conn,'SELECT TOP 1 "name"
    FROM '.$this->table.' WHERE 
    "surname" LIKE ? ');        
    odbc_execute($pstmt,array($ser));  
    return $pstmt;
}

调用代码保持不变

$serTab=$product->reader($ser);
while(odbc_fetch_row($serTab)) 
{ 
    for($i=1;$i<=odbc_num_fields($serTab);$i++) 
    {
        echo odbc_result($serTab,$i);                       
    } 
}

额外注意:你的示例$ser值包含多余单引号,预处理语句会自动处理参数转义,建议把$ser=' \'3221252\'';改成$ser='3221252';;如果需要模糊匹配,应在参数里添加通配符(如$ser='%3221252%';),而非手动拼接单引号。

替代方案

由于PDO因NVARCHAR转ASCII失败无法使用,可考虑以下方案:

  • 使用odbc_exec()结合参数转义:用odbc_escape_string()转义参数后拼接SQL,但这种方式存在SQL注入风险,仅适用于参数完全可控的场景。
  • 调整ODBC驱动字符集配置:在ODBC数据源设置中,尝试将字符集改为UTF-8或对应NVARCHAR的编码(如UTF-16),看是否能解决PDO的转换错误,从而切换到更现代的PDO操作方式。

内容的提问来源于stack exchange,提问作者wittream

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:22:38