【发布时间】:2011-06-30 20:47:18
【问题描述】:
所有 SELECT 都能正常工作。但是,任何 UPDATE 或 INSERT,即使它在 mysql 查询浏览器中执行时有效,同时使用与 PHP 连接到服务器相同的用户登录,但在 PDO 执行时会失败。
举个例子:
SELECT * FROM Projects WHERE ssdUserID = :ssdUserID;
始终正常工作,而
INSERT INTO Projects SET ssdUserID = :ssdUserID, json = :json;
从 PHP 执行时总是失败,尽管我在所有参数上都做了 addlashes()。
我调用 PDO 的方式是通过准备好的语句:
$connection = new PDO("mysql:host=$mysqlServer;
dbname=$mysqlSchema", $mysqlUser, $mysqlPassword);;
$statement = $connection->prepare($sql);
$result = $statement->execute($parameters);
$result 始终为 false,尽管最后发生了提交(暂时出于调试目的),但在数据库中看不到更新或插入。
我启用了 mysql 跟踪日志,似乎 sql 甚至没有发送到 mysql 服务器 - 在跟踪日志中可以看到的只是事务的开始和结束,中间没有任何内容。
由于搜索工作,很明显 PDO 能够建立与数据库的连接。此外,由于搜索使用的代码与不适用于 write 语句的代码相同,因此除了 PDO 本身之外,我想不出任何其他地方有问题。
一个可能很重要的问题是上面示例中的 json 列是文本类型。我已经在另一个地方使用过 PDO,我只有各种 VARCHAR 列,并且在那里它可以正常工作。
有没有人遇到过类似的问题?有人可以帮我解决这个问题吗?
更新:
经过一些挖掘和阅读 (http://www.php.net/manual/en/pdo.lobs.php),我切换到了不同的解决方案。我现在绑定输入参数和输出列。不过,我会保留最初的文本,所以犯同样的最初错误的人可能会比我更容易发现。
绑定参数很容易。我将输出列绑定在一个通用函数中:
01 private function __extractResultsEx($statement, $columns)
02 {
03 $data = array();
04 $msg = "query returned ".$statement->rowCount()." rows";
05 $receiverRow = array();
06 $i = 1;
07 foreach ($columns as $column => $type)
08 {
09 $receiverRow[$column] = NULL;
10 $statement->bindColumn($i++, &$receiverRow[$column], $type);
11 }
12 while ($statement->fetch(PDO::FETCH_BOUND))
13 {
14 $row = array();
15 foreach ($columns as $column => $type)
16 $row[$column] = $receiverRow[$column];
17 $data[] = $row;
18 }
19 return $data;
20 }
列是 ID/PDO::PARAM_INT、userID/PDO::PARAM_INT 和 json/PDO::PARAM_LOB。
我不知道是否需要第 09 行,只是在最初尝试 $receiverRow 最后确实有三个元素但没有初始化之后,我认为这可能会有所帮助 - 但它没有。
使用这种方法,问题是尽管在第 04 行 $statement 说它已经检索到一行,但执行永远不会到达 while 循环内部(第 14 - 17 行),因为 $statement-fetch() 总是返回 false,no无论我使用哪个 PDO::FETCH_ 常量(我尝试了 PDO::FETCH_OBJ、PDO::FETCH_BOUND 和 PDO::FETCH_ASSOC,另一个似乎对 LOB 没有多大意义,无论如何手册页只提到了 PDO: :FETCH_BOUND 用于 LOB)。
上面提到的手册页的 cmets 中记录了一个错误,它说从行中读取 LOB 应该是安全且可以的。尽管如此,我什至在访问行数据之前就出现了问题,尽管我似乎已经按照示例代码中的方式完成了所有操作。
不过,现在有一项改进。 mySQL 跟踪显示我正在执行的 SQL。此外,由于第 04 行提到了我期望的行,我想我已经接近解决方案了 - 但我似乎无法确定它。
【问题讨论】:
-
您当时是否还有另一个打开的连接,可能是您尚未关闭的读取查询?
-
能不能也贴一下绑定参数的代码?