|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2019-03-18 14:11 UTC] m dot a dot ogarkov at gmail dot com
Description:
------------
When binding with SQLT_NUM type, we get NULL in sql/plsql.
Variables is converted to INT, why int?
Test script:
---------------
<?php
declare(strict_types=1);
$handle = oci_connect(getenv("DB_USER"), getenv("DB_PASSWORD"), getenv("DB_HOST"));
$var = 15.123;
$st = oci_parse($handle, "SELECT :0 FROM DUAL");
oci_bind_by_name($st, ":0", $var, -1, SQLT_NUM);
oci_execute($st);
var_dump(oci_fetch_array($st));
var_dump($var);
Expected result:
----------------
we should get NUMBER sql type:
"15.123" => (float) 15.123
"15" => (float) 15
Actual result:
--------------
array(2) {
[0]=>
NULL
[":0"]=>
NULL
}
int(15)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 23:00:01 2025 UTC |
oci_bind_by_name() should reject $type==SQLT_NUM. Bind-type SQLT_NUM will ask oci8 to store/fetch an integer value into/from a 21 byte array where the integer is stored in the oracle-internal NUMBER-format. But the pointer that is used with SQLT_NUM-binds points to an 8-byte integer value (zend_long). It's unpredictable what happens in this case. OCI8 will write 21 bytes into a zend_long-value. This overwrites 13 bytes immediately after the zend_long value and the zend_long-value will have a wrong value. On my machine $conn=oci_new_connect('scott','tiger','ORCL'); $stat=oci_parse($conn, "begin :out:=123; end;"); oci_bind_by_name($stat, ":out", $result, -1, SQLT_NUM); oci_execute($stat); var_dump($result); results in: int(1573570) I think the SQLT_NUM-implementation is missing and SQLT_NUM shoud be rejected until someone has written a conversion-routine between PHP-double and Oracle-NUMBER format.