我想在 Oracle DB 中插入一些 base64 编码的数据(每个字段最多 500.000 个字符)。
因为在我开始使用 PDO 并将字段设置为 CLOB 之前,我没有将 Oracle 与 PHP 一起使用。
我的代码的简短版本(类 Db 扩展了 \PDO):
<?php
Run Code Online (Sandbox Code Playgroud)
[..剪..]
$dbh = new Db( "oci:dbname=" . DB_TNS, DB_USER, DB_PASS );
$Query = ' INSERT INTO "SENTINEL"."SYSTEM_ERRORS"
( BACKTRACE )
VALUES
( :backtrace )
';
$stmt = $dbh->db_prepare( $Query );
$stmt->bindParam( ':backtrace', $backtrace, \PDO::PARAM_LOB );
$backtrace = $someobject->get_backtrace();
$stmt->execute();
print_r($stmt->errorInfo());
$stmt->closeCursor();
Run Code Online (Sandbox Code Playgroud)
我得到:
数组 ( [0] => HY000 [1] => 932 [2] => OCIStmtExecute: ORA-00932: Inkonsistente Datentypen: CLOB erwartet, BLOB erhalten (ext\pdo_oci\oci_statement.c:148) )
任何人都知道如何用 PDO 解决这个问题,所以我不必使用 oci 驱动程序?
我在这里找到了解决方案:
https://bugs.php.net/bug.php?id=57095
[2009-08-11 11:27 UTC] gmail dot com 的 lehresman 写道:
一位同事发现了解决方案。在 Oracle 中使用 PDO 处理 CLOB 时,不要将其视为 LOB。您需要将其绑定为 PDO::PARAM_STR,并为其指定字符串的长度(第 4 个参数是键,否则会失败并显示有关 LONG 类型的错误消息)。
以下是如何在 Oracle 中成功插入 CLOB 的示例:
<?php
/*
CREATE TABLE clob_test (my_clob CLOB)
*/
$big_string = "";
for ($i=0; $i < 10000; $i++)
$big_string .= rand(100000,999999)."\n";
try {
$pdo = new PDO("oci:dbname=TESTDB", "TESTUSER", "TESTPW");
$stmt = $pdo->prepare("INSERT INTO healthbit.clob_test (my_clob) VALUES (:cl)");
$stmt->bindParam(":cl", $big_string, PDO::PARAM_STR, strlen($big_string));
$pdo->beginTransaction();
if (!$stmt->execute()) {
echo "ERROR: ".print_r($stmt->errorInfo())."\n";
$pdo->rollBack();
exit;
}
$pdo->commit();
$stmt = $pdo->prepare("SELECT my_clob FROM healthbit.clob_test");
$stmt->execute();
$row = $stmt->fetch();
$str = "";
while ($tmp = fread($row[0],1024))
$str .= $tmp;
echo strlen($str); // prints 70000
} catch (Exception $e) {
echo "ERROR: ";
echo $e->getMessage();
$pdo->rollBack();
}
Run Code Online (Sandbox Code Playgroud)
对我来说效果很好...