Some queries returns value in binded params.
For example, PL/SQL for Oracle database;
“declare result varchar2(1024); begin :result := ‘Some value…’; end;”
How to use parameters by reference witch Laminas\Db\Adapter\Driver\Oci8\Statement?
I give two samples.
First is pure OCI8 - works fine.
Second is laminas-db wrapper - don’t work.
- First is pure OCI8 - works fine.
`
<?php
// File name "testOci8BindOut.php"
$username = 'myUserLogin';
$password = 'myUserPassword';
$db = "my-database-host/myDatabaseSID";
try {
$conn = oci_connect($username, $password, $db);
if (!$conn) {
$m = oci_error();
trigger_error(htmlentities($m['message']), E_USER_ERROR);
}
$sql = <<<SQL
--set serveroutput on;
declare
result varchar2(1024);
begin
:result := 'Now ' || to_char(sysdate, 'YYYY-MM-DD_HH24-MI-SS');
--DBMS_OUTPUT.put_line(:result);
end;
SQL;
$ociStatement = oci_parse($conn, $sql);
$resultParamName = 'result';
$resultParamValue = 'Current value will be replaced';
oci_bind_by_name($ociStatement, $resultParamName, $resultParamValue, -1, SQLT_CHR);
$ret = @oci_execute($ociStatement, OCI_COMMIT_ON_SUCCESS);
if ($ret === true) {
var_dump(array(
'success' => true,
'result' => $resultParamValue
));
} else {
$errData = oci_error($ociStatement);
var_dump(array(
'success' => false,
'result' => $resultParamValue,
'errData' => $errData
));
}
oci_free_statement($ociStatement);
oci_close($conn);
} catch (Exception $err) {
var_dump(array(
'success' => false,
'result' => 'Exception',
'error' => $err
));
}
`
request to http://localhost:8080/tests/testOci8BindOut.php
answer
[
‘success’ => true,
‘result’ => ‘Now 2020-12-10_10-27-25’
]
As you can see, value in $resultParamValue replaced from ‘Current value will be replaced’ to ‘Now 2020-12-10_10-27-25’
- Second is laminas-db wrapper - don’t work.
`
<?php
// File name is "testOci8BindOutLaminas.php"
include_once '../../vendor/autoload.php';
$username = 'myUserLogin';
$password = 'myUserPassword';
$dbConnString = "my-database-host/myDatabaseSID";
$driverConfig = [
'driver' => 'Oci8',
'hostname' => $dbConnString, //Синонимы ключа ['connection_string','connectionstring','connection','hostname','instance']
'username' => $username,
'password' => $password,
//'schema' => 'myschema',
'charset' => 'AL32UTF8', // Синонимы ключа ['character_set', 'charset', 'encoding']
// 'unique' => false, // true - oci_new_connect; false - oci_pconnect|oci_connect
// 'persistent' => false, // true - oci_pconnect
// 'session_mode' => ?,
'profiler' => false,
'platform_options' => [
'quote_identifiers' => false
],
];
try {
$dbAdapter = new Laminas\Db\Adapter\Adapter($driverConfig);
$sql = <<<SQL
--set serveroutput on;
declare
result varchar2(1024);
begin
:result := 'Now ' || to_char(sysdate, 'YYYY-MM-DD_HH24-MI-SS');
--DBMS_OUTPUT.put_line(:result);
end;
SQL;
$laminasStatement = $dbAdapter->createStatement($sql);
$params = [
'result' => 'Current value will be replaced'
];
$paramsContainer = new \Laminas\Db\Adapter\ParameterContainer($params);
// $laminasResult = $laminasStatement->execute($params); // We lost referene to 'result' param
$laminasStatement->setParameterContainer($paramsContainer); // We have reference to 'result' param by object "$paramsContainer"
$laminasResult = $laminasStatement->execute();
$resultParamValue = $paramsContainer->offsetGet('result');
if ($laminasResult instanceof \Laminas\Db\Adapter\Driver\ResultInterface ) {
var_dump(array(
'success' => true,
'result' => $laminasResult,
'$resultParamValue' => $resultParamValue
));
} else {
$ociStatement = $laminasStatement->getResource();
$errData = oci_error($ociStatement);
var_dump(array(
'success' => false,
'result' => $resultParamValue,
'errData' => $errData
));
}
} catch (Exception $err) {
var_dump(array(
'success' => false,
'result' => 'Exception',
'error' => $err
));
}
`
request to http://localhost:8080/tests/testOci8BindOutLaminas.php
answer:
[
‘success’ => true,
‘result’ => …//object(Laminas\Db\Adapter\Driver\Oci8\Result)[…
‘$resultParamValue’ => ‘Current value will be replaced’
]
As you can see, value of ‘$resultParamValue’ is wrong.
Class Laminas\Db\Adapter\Driver\Oci8\Statement uses variable from by copy, instead ising by reference!