2012-06-07 21 views
2

2天后爭奪,我試着問幫助在這裏。我正在使用unixODBC(2.2.11)在CentOS 5.4服務器上使用DB2(iSeries)和PHP(5.3)。我想這是PHP從5.1升級到5.3之後,我在某些查詢中讓PHP陷入了段錯誤。經過一番調查,我發現它會出現在查詢長炭領域的問題,例如與此表:段錯誤與unixODBC數據(DB2)+ PHP + CentOS的

TABLE (
    CONTRACTID NUMERIC, 
    SOMETEXT CHAR(583) 
) 

這一段簡單的代碼引發了段錯誤:

try { 
    $conn = new PDO("odbc:".$dsn, $username, $password, array(
     PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) 
    ); 
} 
catch (Exception $e) { 
    echo $e->getMessage(); 
} 

$sql = 'SELECT * FROM LIB.TABLE '; 
$stmt = $conn->prepare($sql); 
$vals = $stmt->execute(); 
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 

是否有任何列長度限制還是unixODBC和/或PHP> 5.1的錯誤? 這個Web應用程序工作得非常好,然後我進入這個問題..

順便說一句,我測試了一個更新的64位CentOS 6.2機與unixODBC 2.2.14和PHP 5.3,問題是相同。

任何幫助非常感謝,

感謝

法比安斯基

UPDATE: 使用PHP ODBC函數,它的工作原理:

$conn = odbc_connect($dsn, $username, $password); 
$res = odbc_exec($conn, $sql); 
$rows = odbc_fetch_array($res); 

所以問題更加綁到PDO,有什麼想法?

回答

5

我不能說我知道的PDO(其中反正我不使用)的任何問題或unixODBC數據或DB2驅動程序。我不是從你的電子郵件確認,如果你的第一平臺使用的是64位建立或32位建立,但是ODBC改變時,微軟增加了64位支持(見SQLLEN/SQLULEN and 32/64 bit platforms64-bit ODBC)。基本上,一些ODBC API的類型已從SQLINTEGER更改爲SQLLEN,並且SQLLEN在64位版本中爲64位,在32位版本中爲32位。然而,由於沒有人知道微軟是要做到這一點,其中的一些參數在規格爲32個位數一些ODBC驅動程序開發者已經建立的ODBC驅動程序使用的是32位的,這些論點64個平臺實際上描述。顯然,如果你將一個應用程序或驅動程序管理器與一個驅動程序構建成一個驅動程序,那麼所有的驅動程序都可能會丟失,而且你很可能會發生段錯誤。因此,首先,如果您使用64位二進制文​​件,則需要檢查ODBC驅動程序是否已正確構建 - 請與IBM聯繫。

的unixODBC 2.2.11現在已很舊,我知道問題已得到修復,但我仍然使用它廣泛,只有在光標庫中的一個小問題。無論如何,你試過2.2.14,問題是一樣的。我懷疑這是一個unixODBC問題,但這只是基於我對它的豐富經驗,而不是因爲我知道一個事實。

現在,假設你不屬於以上任何你描述的情況可以做一些事情。嘗試在unixODBC中啓用日誌記錄,然後您可以看到正在調用哪些ODBC調用以及哪個調用失敗。您也可能會從所傳達的論點中得知線索。啓用加入登錄以下到您的ODBCINST.INI文件:

[ODBC] 
Trace=yes 
TraceFile=/tmp/unixodbc.log 

查找到SQLBindCol或SQLGetData呼籲有問題的列。如果這不能讓你在任何地方,你可以嘗試粘貼它的結尾,我會看看它。

如果您可以從命令行運行PHP程序並安裝gdb,則可以在gdb下運行它,它會向您顯示發生問題的位置的堆棧轉儲。只要執行gdb/path/to/php然後鍵入r myscript.php並輸入以運行它,當它發生段錯誤時,可以使用bt(backtrace)命令來顯示堆棧。這應該確定哪些代碼導致段錯誤,儘管它不一定是錯誤的代碼(例如,如果php傳遞了一個指向10字節的緩衝區的指針,但位於並且表示它是100字節,則寫入結尾的代碼不是有過錯)。

9

這裏出現同樣的問題。發現當返回一個NULL值的字段時,64位php-odbc模塊導致seg錯誤。解決方法是合併每個可能存在NULL值的字段。這不是一個好的解決方案。我正在查看php-odbc.c代碼,但我無法保證修復。

解決方法: SELECT COALESCE(CHAR(字段名), '')FROM ...

我想我會用一個32位的版本替換該服務器。我有其他人工作得很好。

+0

我也遇到這個問題 - Ubuntu 11.04/PHP 5.3.5產生的問題,而openSUSE 12.1/PHP 5.3.15正常工作。我認爲這是PHP版本,但我仍在研究php-odbc。你有沒有找到一個解決方案,沒有使用coalesce? – MaKR

+1

可以確認,它適用於5.3.10版本的php 32。它在PHP 5.4中修復,這裏是相關的錯誤https://bugs.php.net/bug.php?id=61387 – kevin

6

我在使用Vertica 6和CentOS附帶的UnixODBC的Centos 6.3上遇到了類似的問題,PHP只是段錯誤。於是我就strace php mytest.php,發現它試圖找到並打開/usr/lib64/libodbccr.so.1

但Centos的6.3只有libodbccr.so.2

所以快速和骯髒的解決辦法是做好以下幾點:/usr/lib64

LN - s libodbccr.so.2 libodbccr.so.1

使用需要您自擔風險!

+0

這也適用於我。 – gerard

+0

非常棒! :D – AntonioCS

+0

相同的問題,但在Ubuntu 16.04。 「strace」向我展示了這個問題。用'sudo apt-get install unixodbc-dev'解決 – shadi