我在具有类似CLOB数据的表中有2条记录。其中每一个都是从查询中解析出来的,然后通过php在一个循环中读取一个字符串,对着返回的PDO :: FETCH_ASSOC
在查询返回结果后,它看起来像这样:
ID | NAME | DESCRIPTION | LOB_DEFINITION
4409 foo blah blah long text that is stored in a lob ~ 5k characters
4410 foobar blah blah some other long text stored in a lob ~ 5k characters
我的问题是,一旦我开始循环并从LOB中读取内容,它们就不会“重置”所以,读取的任何和所有对象都将具有与它读取的第一个LOB相同的值:
类似的东西:
foreach($result as $r) {
$lob = stream_get_contents($r['LOB_DEFINITION']);
echo $r['ID'].'-<i>'.$lob.'</i><HR>';
unset($lob);
}
会产生如下输出:
4409- 长文本存储在一个高约5k个字符
中4410- 长文本存储在一个高约5k个字符
中而不是我期望获得的内容:
4409- 长文本存储在一个高约5k个字符
中4410- 一些其他长文本存储在一个高约5k个字符
中我也检查了资源ID,它们是不同的资源......
我在这里不知所措......有没有人对这个问题有所了解?
答案 0 :(得分:1)
几个小时的研究得出以下结论:
从oracle表返回多记录集,其中一列是clob数据类型,将导致检索到的最后一条记录clob成为检索到的所有clob的值。这就是造成上述行为的原因。
我最终要解决的问题是:
选择我计划使用clobs的所有记录(不是clobs本身,只是记录ID)
然后,我循环遍历这些记录ID,并使用单独的数据库调用,使用主键逐个处理CLOB数据以提取记录,以确保回送数据不超过1条记录。所以从本质上说现在正在发生的事情:
从表中检索我想要使用的所有clob的ID后,我就这样解析了它们:
foreach($result as $r) {
$query = 'select lob_definition from mytable where id = '.$r;
$lobresult = oracleConnection->query($query)->fetchAll(FETCH_COLUM);
$lob = stream_get_contents($lobresult);
echo $r['ID'].'-<i>'.$lob.'</i><HR>';
unset($lob);
}
这种效果已经解决了我的问题(所有这些都是用各种方法抽象出来的,但基本上就是发生了什么。
答案 1 :(得分:0)
这是由于PDO(OCI):: fetchAll中的长期错误 https://bugs.php.net/bug.php?id=46728
您不必像Jeffs答案那样对每一行进行单独的查询。您只需要避免fetchAll。根据错误说明中建议的解决方法,我正在使用以下函数来获取所有LOB:
function fetchAllLOB(PDOStatement $stmt): array
{
$result = [];
while ($row = $stmt->fetch()) {
foreach ($row as $name => $value) {
if (is_resource($value)) {
$row[$name] = stream_get_contents($value);
}
}
$result[] = $row;
}
return $result;
}