Yii 1.1 oci8Pdo extension and CLOB / BLOB parameter bind

My company has a project that is built on Yii 1.1 and uses the Oracle 9g database. To work with the base, the oci8Pdo extension is used .

Recently there was a task of loading scans to the database in the BLOB field. Because the author of the extension writes:
The goal of this PDO class is to simulate 99% of the PDO functions that you use in an application.
then there were few reasons to doubt the implementation of this functionality.

Try to load the scan:

dbOracle;
    $stmt = $db->createCommand("update scan_document set DOCUM_SCAN=:doc_xml, DOC_SCAN=:doc_scan where DOCUM_ID=:docum_id");
    $stmt->bindParam(':doc_xml', $doc_xml, PDO::PARAM_LOB);
    $stmt->bindParam(':doc_scan', $doc_scan, PDO::PARAM_LOB);
    $stmt->bindValue(':docum_id', $add->DOCUM_ID);
    $stmt->query();
?>

But there it was: ORA-01465: invalid hex number.

They began to light up the problem and stumbled upon the implementation of the bindParam method in the Oci8PDO_Statement class of the extension described above:

_sth,
            $parameter,
            $variable,
            count($variable),
            $length
        );
    } else {
        if ($length == -1) {
            $length = strlen((string)$variable);
        }
        return oci_bind_by_name($this->_sth, $parameter, $variable, $length);
    }
}
?>

The $ data_type argument is accepted, but not processed anywhere. So it turns out that CLOB or BLOB write with us will not work. There was nowhere to go, I had to finish oci8Pdo.

In the class Oci8PDO which is inherited from PDO, constants and the method of pulling out the connection resource to the DB were added:

_dbh;
    }
?>

And a little bit finished with the bindParam method in the Oci8PDO_Statement class:

_pdoOci8->getDbh(), OCI_D_LOB);
            $res = oci_bind_by_name($this->_sth, $parameter, $clob, -1, OCI_B_BLOB);
            $clob->writeTemporary($variable, OCI_TEMP_BLOB);
            return $res;
        } else if ($data_type == Oci8PDO::PARAM_CLOB) {
            $clob = oci_new_descriptor($this->_pdoOci8->getDbh(), OCI_D_LOB);
            $res = oci_bind_by_name($this->_sth, $parameter, $clob, -1, OCI_B_CLOB);
            $clob->writeTemporary($variable, OCI_TEMP_CLOB);
            return $res;
        }
        else {
            return oci_bind_by_name($this->_sth, $parameter, $variable, $length);
        }
    }
?>

Now CLOB / BLOB processing is successful:

dbOracle;
$stmt = $db->createCommand("update scan_document set DOCUM_SCAN=:doc_xml, DOC_SCAN=:doc_scan where DOCUM_ID=:docum_id");
$stmt->bindParam(':doc_xml', $doc_xml, Oci8PDO::PARAM_CLOB); // Используем наши константы
$stmt->bindParam(':doc_scan', $doc_scan, Oci8PDO::PARAM_BLOB); // Используем наши константы
$stmt->bindValue(':docum_id', $add->DOCUM_ID);
$stmt->query();
?>

Bottom line:

Dopil was organized into a pullrequest and sent to the developer oci8Pdo yjeroen . When the problem was googled, many unresolved questions on this topic were noticed. I hope my experience helps someone.

PS: I will be glad to criticism and constructive comments in the comments.

Also popular now: