When I use the Oracle PHP function oci_bind_array_by_name(), it converts all nulls in my array to 0s for any number fields and 0-length strings for varchar2s. The official documentation does not mention this behavior. Is it a bug? Is it intended? If intended, is there some setting or parameter I can change to keep nulls as nulls?
Here is a short example:
<?php
$db = oci_pconnect($userId, $password, $connectionString);
if (!$db) {
echo 'Could not connect to DB.<br />';
die();
}
$sql = 'BEGIN test_proc(:number, :integer, :varchar, :float); END;';
$stmt = oci_parse($db, $sql);
if (!$stmt) {
print_r(oci_error($db));
die();
}
$number = [null, 0, 1];
$integer = [null, 0, 1];
$float = [null, 0.0, 1.1];
$varchar = [null, '', 'test'];
echo '<h1>Before using oci_bind_array_by_name</h1>';
echo 'Number array:';
var_dump($number);
echo 'Integer array:';
var_dump($integer);
echo 'Float array:';
var_dump($float);
echo 'VarChar2 array:';
var_dump($varchar);
$bind = oci_bind_array_by_name($stmt, ':number', $number, count($number), -1, SQLT_NUM);
$bind = oci_bind_array_by_name($stmt, ':integer', $integer, count($integer), -1, SQLT_INT);
$bind = oci_bind_array_by_name($stmt, ':float', $float, count($float), -1, SQLT_FLT);
$bind = oci_bind_array_by_name($stmt, ':varchar', $varchar, count($varchar), -1, SQLT_CHR);
echo '<h1>After using oci_bind_array_by_name</h1>';
echo 'Number array:';
var_dump($number);
echo 'Integer array:';
var_dump($integer);
echo 'Float array:';
var_dump($float);
echo 'VarChar2 array:';
var_dump($varchar);
The output is:
Before using oci_bind_array_by_name
Number array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:23:
array (size=3)
0 => null
1 => int 0
2 => int 1
Integer array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:25:
array (size=3)
0 => null
1 => int 0
2 => int 1
Float array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:27:
array (size=3)
0 => null
1 => float 0
2 => float 1.1
VarChar2 array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:29:
array (size=3)
0 => null
1 => string '' (length=0)
2 => string 'test' (length=4)
After using oci_bind_array_by_name
Number array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:38:
array (size=3)
0 => int 0
1 => int 0
2 => int 1
Integer array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:40:
array (size=3)
0 => int 0
1 => int 0
2 => int 1
Float array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:42:
array (size=3)
0 => float 0
1 => float 0
2 => float 1.1
VarChar2 array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:44:
array (size=3)
0 => string '' (length=0)
1 => string '' (length=0)
2 => string 'test' (length=4)
When I use the Oracle PHP function oci_bind_array_by_name(), it converts all nulls in my array to 0s for any number fields and 0-length strings for varchar2s. The official documentation does not mention this behavior. Is it a bug? Is it intended? If intended, is there some setting or parameter I can change to keep nulls as nulls?
Here is a short example:
<?php
$db = oci_pconnect($userId, $password, $connectionString);
if (!$db) {
echo 'Could not connect to DB.<br />';
die();
}
$sql = 'BEGIN test_proc(:number, :integer, :varchar, :float); END;';
$stmt = oci_parse($db, $sql);
if (!$stmt) {
print_r(oci_error($db));
die();
}
$number = [null, 0, 1];
$integer = [null, 0, 1];
$float = [null, 0.0, 1.1];
$varchar = [null, '', 'test'];
echo '<h1>Before using oci_bind_array_by_name</h1>';
echo 'Number array:';
var_dump($number);
echo 'Integer array:';
var_dump($integer);
echo 'Float array:';
var_dump($float);
echo 'VarChar2 array:';
var_dump($varchar);
$bind = oci_bind_array_by_name($stmt, ':number', $number, count($number), -1, SQLT_NUM);
$bind = oci_bind_array_by_name($stmt, ':integer', $integer, count($integer), -1, SQLT_INT);
$bind = oci_bind_array_by_name($stmt, ':float', $float, count($float), -1, SQLT_FLT);
$bind = oci_bind_array_by_name($stmt, ':varchar', $varchar, count($varchar), -1, SQLT_CHR);
echo '<h1>After using oci_bind_array_by_name</h1>';
echo 'Number array:';
var_dump($number);
echo 'Integer array:';
var_dump($integer);
echo 'Float array:';
var_dump($float);
echo 'VarChar2 array:';
var_dump($varchar);
The output is:
Before using oci_bind_array_by_name
Number array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:23:
array (size=3)
0 => null
1 => int 0
2 => int 1
Integer array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:25:
array (size=3)
0 => null
1 => int 0
2 => int 1
Float array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:27:
array (size=3)
0 => null
1 => float 0
2 => float 1.1
VarChar2 array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:29:
array (size=3)
0 => null
1 => string '' (length=0)
2 => string 'test' (length=4)
After using oci_bind_array_by_name
Number array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:38:
array (size=3)
0 => int 0
1 => int 0
2 => int 1
Integer array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:40:
array (size=3)
0 => int 0
1 => int 0
2 => int 1
Float array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:42:
array (size=3)
0 => float 0
1 => float 0
2 => float 1.1
VarChar2 array:
/home/toomanycooks/public_html/bulk_insert_nulls.php:44:
array (size=3)
0 => string '' (length=0)
1 => string '' (length=0)
2 => string 'test' (length=4)
After reviewing the oci source code, it looks like there is no way to use nulls with oci_bind_array_by_name.
empty()
to post-process and convert back? Or keep a copy of the array and compare the two afterwards? – Alex Howansky Commented Jan 2 at 15:50oci_bind_by_name
does this, too. Are you able to test that? This note is curious, but I don't know if it is related or not. – Chris Haas Commented Jan 2 at 20:40