在过去的两天中,我一直在使用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