PDO Prepared Statement over ODBC Sybase“PARAM 数据流”错误

Posted

技术标签:

【中文标题】PDO Prepared Statement over ODBC Sybase“PARAM 数据流”错误【英文标题】:PDO Prepared Statement over ODBC Sybase "PARAM datastream" error 【发布时间】:2012-10-19 07:20:07 【问题描述】:

我正在尝试将一些旧的 php ODBC 查询转换为 PDO Prepared 语句,并收到一个错误,我找不到太多信息。

错误是:

"[DataDirect][ODBC Sybase Wire Protocol driver][SQL Server]没有对应于 PARAM 数据流指定的宿主变量。这意味着在前面的 DECLARE CURSOR 或 SQL 中没有使用此变量''命令。(SQLExecute[3801] at ext\pdo_odbc\odbc_stmt.c:254)"

我正在使用 6 位 ID 在数据库中搜索单行,该 ID 作为 VARCHAR 存储在数据库中,但通常是 6 位数字。

数据库连接报告成功。

查询字符串传递的 ID 被验证。

prepared statement导致上述错误。

else 子句中的直接备份 ODBC_EXEC 语句返回我要查找的数据。

//PDO Driver Connect to Sybase
try 
    $pdo = new PDO("odbc:Driver=Sybase ASE ODBC Driver;NA=server,5000;Uid=username;Pwd=password;");
    $pdo_status = "Sybase Connected";
 catch(PDOException $e) 
    echo 'Connection failed: ' . $e->getMessage();



if((isset($_GET['id'])) AND ($_GET['id'] != "")) 

//Validate ID String
if(!preg_match("/^[A-Za-z0-9]5,7/",$_GET['id'])) 
    $query1_id = FALSE;
    echo "Invalid ID";
    exit;
 else 
    $query1_id = $_GET['id'];


$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ?");
$query1->execute(array($query1_id));
if($query1->errorCode() != 0) 
        $person_data = $query1->fetch(PDO::FETCH_ASSOC);    
        echo "Person Data from PDO: ";
        print_r($person_data);
     else 
        $errors = $query1->errorInfo();
        echo $errors[2];
//Try the old way to confirm data is there.
        $odbc_query1 = "SELECT * FROM People WHERE PersonId='$query1_id' ";
        $person_result = odbc_exec($conn,$odbc_query1) or die("Error getting Data, Query 1");
        $person_data = odbc_fetch_array($person_result);
        echo "Person Data from ODBC_EXEC: ";
        print_r($person_data);
    

如果我使用它也会失败:

$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->execute(array(":id"=>$query1_id));

有人遇到过这个错误吗?

编辑:Sybase 手册说明了这个错误...

错误 3801:没有对应于 PARAM 数据流指定的主机变量。这意味着这个变量 `%.*s' 没有在前面的 DECLARE CURSOR 或 SQL 命令中使用。

解释: Adaptive Server 无法执行请求的操作。检查您的命令是否缺少或不正确的数据库对象、变量名称和/或输入数据。

这很奇怪,因为我的错误(在顶部引用)没有告诉我哪个变量没有主机。

如果我使用...也会失败

$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= :id ");
$query1->bindParam(':id',$query1_id,PDO::PARAM_STR);  //Or PARAM_INT
$query1->execute();

如果我像这样将变量放在查询中,则查询有效...

$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");

所以我认为这与参数未绑定到占位符有关,但我不知道为什么。

如果我不能解决这个问题,我将不得不恢复将查询构建为字符串,并希望我的输入验证是防弹的。

【问题讨论】:

您是否尝试过将 $query1_id 转换为字符串并设置长度? $query1->bindParam(':id',(string) $query1_id,PDO::PARAM_STR, 6); ? 【参考方案1】:

您的问题似乎与 PHP 分配给占位符中的变量的默认数据类型有关。 SQL 语句正在寻找一个数字,但 PHP 将其解释为其他内容。您可以使用占位符变量周围的引号来防止这种情况。请注意,在有效的语句中,PHP 看到的值周围有撇号 (''):

$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= '$query1_id'");

使用占位符时试试这个应该是一样的:

$query1 = $pdo->prepare("SELECT * FROM People WHERE PersonId= ':id'"); 

【讨论】:

以上是关于PDO Prepared Statement over ODBC Sybase“PARAM 数据流”错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在SELECT FROM PDO Prepared Statement中为搜索框设置多个搜索条件?

PDO Prepared Statement over ODBC Sybase“PARAM 数据流”错误

Laravel - PDO Prepared Statement - 在其他无缓冲查询处于活动状态时无法执行查询

Prepared SQL Statement Syntax

PDO Prepared在单个查询中插入多行

使用 Prepared Statement 设置 LONG 数据类型