2015-02-06 87 views
0

我目前正在将PHP项目从使用PHP的mssql库迁移到使用带有FreeTDS的PDO库。我修改了所有的数据库调用,但在SQL Server数据库上执行预准备语句时遇到了一个非常奇怪的问题。PHP PDO的分段错误FreeTDS ODBC执行

下面是我遇到问题的代码片段。

public static function gift_cards_exist($start_number, $end_number = null) { 
    global $sol_donations; 
    $db = $sol_donations->get_db(); 

    $store_id = get_option('pos-store-id', false); 
    //$store_id = '01'; // Won't work if value assigned this way 
    $payment_method = 'Gift'; 

    if (empty($end_number)) { 
     $end_number = $start_number; 
    } 

    $query = ' 
     SELECT * FROM dbo.tblPmtSerialHdr 
     WHERE SerialId BETWEEN ? AND ? 
     AND StoreId = ?'; 
     //AND PmtMethodId = ?'; 

    $stmt = $db->prepare($query); 
    $stmt->bindParam(1, $start_number, \PDO::PARAM_STR | \PDO::PARAM_INPUT_OUTPUT); 
    $stmt->bindParam(2, $end_number, \PDO::PARAM_STR | \PDO::PARAM_INPUT_OUTPUT); 
    $stmt->bindParam(3, $store_id, \PDO::PARAM_STR | \PDO::PARAM_INPUT_OUTPUT); 
    //$stmt->bindParam(4, $payment_method, \PDO::PARAM_STR | \PDO::PARAM_INPUT_OUTPUT); 
    $result = $stmt->execute(); 

    $result = $stmt->fetchAll(\PDO::FETCH_ASSOC); 
    $stmt->closeCursor(); 

    /* Nothing printed from this 
    echo $stmt->errorCode(); 
    echo '<br />'; 
    echo $stmt->errorInfo(); 
    */ 
    var_dump($result); 
    exit(); 

    if ($result) { 
     return true; 
    } 
    return false; 
} 

这是问题存在的地方。以这种形式运行代码(所有注释行都保留注释)会导致查询的执行结果与预期的一致,但对于我的程序而言结果不正确。

但是,如果我修改查询以使用第二个AND语句并取消注释最后一个bindParam语句以与语句一起使用,则该脚本将失败,从而导致分段错误。我在apache的错误日志中获得实际的错误信息是:

[Fri Feb 06 10:43:05.406772 2015] [core:notice] [pid 1415] AH00051: child pid 1541 exit signal Segmentation fault (11), possible coredump in /etc/apache2 

我完全不知道为什么这增加一个额外的参数准备语句是导致问题。

有关情况的一些额外的信息:

freetds的安装是否正确,可用于连接到数据库和查询数据。

我已经尝试使用bindParambindValue两者都给出了相同的结果。

我试着运行声明,并且没有按位或用PDO::PARAM_INPUT_OUTPUT

最后,我检查了一下,确保记录集中没有NULL应该返回以确保NULL值不可能是原因。

+0

您应该可以与freetds人交谈并报告软件中的错误。 – 2015-02-06 16:53:30

回答

1

因此,事实证明这是FreeTDS ODBC驱动程序中的某种错误。我切换到使用dblib驱动程序,我的所有查询都正常工作,没有分段错误。

0

有一个类似的问题,我通过PDO和DBLIB运行的查询返回一个钱类型值。 我不得不使用的DBLIB版本在apache和google中导致了分段错误,导致我这样做。

简单地将钱类型值转换为小数意味着我可以解决这个问题,同时仍然保持小数精度。