在過去的兩天中,我一直在使用PDO與Vertica連接時遇到了一個非常奇怪的錯誤。你看,以下腳本的工作原理如下:Vertica和PDO準備的語句
$c = new PDO("odbc:Driver=Vertica;Server=x.x.x.x;Port=5433;Database=db;", "MyUser", "MyPassword");
$c->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $c->prepare("SELECT * FROM myClients WHERE ClientNum = 88");
$stmt->execute();
之後,我遍歷結果並顯示它們沒有問題。這基本上意味着我的連接是正確的,否則我不會從數據庫中得到任何東西。在另一方面,下面讓Apache服務器完全重置連接(在Windows中運行的時候,我得到一個消息,阿帕奇墜毀):
$c = new PDO("odbc:Driver=Vertica;Server=x.x.x.x;Port=5433;Database=db;", "MyUser", "MyPassword");
$c->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$c->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
//$c->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
try
{
$stmt = $c->prepare("SELECT * FROM myClients WHERE ClientNum = :cl");
$stmt->bindValue(":cl", 88);
$stmt->execute();
while($res = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo $res['noClient'] . "<br>";
}
}
catch(Exception $e)
{
echo $e->getMessage();
}
的問題是同時存在於Linux和Windows,我使用Vertica V7.0.2-1以及相應的ODBC驅動程序。 Vertica 6.1中也存在這個問題。任何人都可以幫我一把嗎?
在此先感謝。
編輯:我試圖設置PDO :: ATTR_EMULATE_PREPARES真假沒有任何改變。
編輯:這是一個測試腳本,我沒有打擾任何錯誤處理。另外,鑑於服務器實際崩潰,我懷疑它會改變任何事情。
編輯:更新了上面的代碼以包含一些基本的錯誤處理。在我早些時候的評論中,Kermit對於聽起來居高臨下的道歉抱歉。無論如何,即使對我的代碼添加了這些內容,我仍然沒有收到任何消息,服務器只會默默地崩潰,我會得到一個「連接重置」頁面。看到這個,我試着查詢我的數據庫中的不同表格,並在一個,而不是崩潰,我得到以下:
SQLSTATE [HY000]:一般錯誤:50310 [Vertica] [Support](50310)Unrecognized ICU轉換錯誤。 (SQLExecute [50310]在內線\ PDO_ODBC \ odbc_stmt.c:254)
編輯:去我的ODBC DSN,點擊配置,走到服務器設置選項卡上,發現區域被設置爲:EN_US @整理= binary(我相信這是Vertica的默認設置)。我應該檢查別的地方嗎?
編輯:我很好奇,看看bindValue()對我的查詢做了什麼,因此打開了vertica.log文件。以下是我所看到的:
2014-10-02 11:38:42.100 Init Session:0x5ef3030 [Session] <INFO> [Query] TX:0(vertica-1756:0xbc42) set session autocommit to on
2014-10-02 11:38:42.104 Init Session:0x5ef3030 [Session] <INFO> [PQuery] TX:0(vertica-1756:0xbc42) SELECT * FROM myClients WHERE ClientNum = ?
2014-10-02 11:38:42.105 Init Session:0x5ef3030-a00000000aac68 [Txn] <INFO> Begin Txn: a00000000aac68 'SELECT * FROM myClients WHERE ClientNum = ?'
2014-10-02 11:38:42.915 Init Session:0x5ef3030-a00000000aac68 <LOG> @v_flexgroup_node0001: 08006/2895: Could not receive data from client: No such file or directory
2014-10-02 11:38:42.915 Init Session:0x5ef3030-a00000000aac68 <LOG> @v_flexgroup_node0001: 08006/5167: Unexpected EOF on client connection
2014-10-02 11:38:42.915 Init Session:0x5ef3030-a00000000aac68 <LOG> @v_flexgroup_node0001: 00000/4719: Session vertica-1756:0xbc42 ended; closing connection (connCnt 2)
2014-10-02 11:38:42.916 Init Session:0x5ef3030-a00000000aac68 [Txn] <INFO> Rollback Txn: a00000000aac68 'SELECT * FROM myClients WHERE ClientNum = ?'
顯然,看起來PDO在最終查詢中用問號代替佔位符。並非所有這些意想不到的,但由於某種原因,參數的實際值似乎在一路上迷路了。
編輯:下面一個建議,我想:
$stmt = $c->prepare("SELECT * FROM myClients WHERE ClientNum = :cl");
$stmt->execute(array(":cl" => 88));
但問題依舊。
嘗試反轉爲'PDO :: ATTR_EMULATE_PREPARES'當前設置。如果它現在是'true',則將其設爲'false',反之。我懷疑你現在沒有使用模擬的準備工作,但是這樣做可能會有所幫助,因爲在發送到RDBMS之前,PDO/PHP將處理所有的參數綁定和替換。 (我有Vertica的沒有經驗) – 2014-10-01 20:27:18
這裏記錄http://php.net/manual/en/pdo.setattribute.php – 2014-10-01 20:28:18
哪裏是你的錯誤處理? – Kermit 2014-10-01 20:52:43