Open
Description
Description
The following code:
<?php
$sql = 'SELECT :a a, dump(:a) a_type, :b b, dump(:b) b_type, '
. '4 num, dump(4) num_type, \'4\' str, dump(\'4\') str_type, '
. '(select 1 from dual where \'04\' = :a) a_where, '
. '(select 1 from dual where \'04\' = 4) num_where '
. 'FROM dual';
$num = 4;
$str = '4';
// test oci8 ext
$conn = oci_connect('system', 'atk4_pass', '127.0.0.1/xe');
$statement = oci_parse($conn, $sql);
oci_bind_by_name($statement, ':a', $num, -1, SQLT_INT);
oci_bind_by_name($statement, ':b', $str);
oci_execute($statement);
$row = oci_fetch_array($statement, OCI_ASSOC);
print_r($row);
var_dump($row['A_WHERE']);
// test pdo_oci
$pdo = new \PDO('oci:dbname=127.0.0.1/xe', 'system', 'atk4_pass');
$statement = $pdo->prepare($sql);
$statement->bindValue(':a', $num, \PDO::PARAM_INT);
$statement->bindValue(':b', $str);
$statement->execute();
$row = $statement->fetch(\PDO::FETCH_ASSOC);
print_r($row);
var_dump($row['A_WHERE']);
Expected output:
- actual
+ expected
Array
(
[A] => 4
[A_TYPE] => Typ=2 Len=2: 193,5
[B] => 4
[B_TYPE] => Typ=1 Len=1: 52
[NUM] => 4
[NUM_TYPE] => Typ=2 Len=2: 193,5
[STR] => 4
[STR_TYPE] => Typ=96 Len=1: 52
[A_WHERE] => 1
[NUM_WHERE] => 1
)
string(1) "1"
Array
(
[A] => 4
- [A_TYPE] => Typ=1 Len=1: 52
+ [A_TYPE] => Typ=2 Len=2: 193,5
[B] => 4
[B_TYPE] => Typ=1 Len=1: 52
[NUM] => 4
[NUM_TYPE] => Typ=2 Len=2: 193,5
[STR] => 4
[STR_TYPE] => Typ=96 Len=1: 52
- [A_WHERE] =>
+ [A_WHERE] => 1
[NUM_WHERE] => 1
)
-NULL
+string(1) "1"
As you can see, oci8
binds the parameter with correct type, but pdo_oci
has a bug. pdo_oci
needs to be fixed as binding with incorrect type have implications as shown in the example ('04' = 4
is true, but '04' = '4'
is not).
In other DBs (I tested MySQL, PostgreSQL, T-SQL/MSSQL) PDO seems to be honoring the bind type correctly.
Can be tested localy using Dockerized Oracle Database:
docker run -it -p 1521:1521 -eORACLE_PASSWORD=atk4_pass gvenzl/oracle-xe:18-slim-faststart
PHP Version
any
Operating System
any