yajra / pdo-via-oci8

PHP PDO_OCI functions via OCI8 extension
Other
88 stars 61 forks source link

Problem with bind param oci collection #73

Closed barrigapicante closed 4 years ago

barrigapicante commented 4 years ago

Hello man, thanks to you for your work,

Problem and code

I have this procedure and type in my oracle DB, the idea is use a collection like parameter, this is an example

CREATE OR REPLACE TYPE ARRAY_DATOS2 IS VARRAY(100) OF varchar2(500);

CREATE OR REPLACE PROCEDURE PRUEBA_VARRAY2(P_TIP IN VARCHAR2,P_CUR IN OUT ARRAY_DATOS2) IS
v_num number;
BEGIN
-- this line insert size of collection in table ARAUCANO
  v_num:=P_CUR.count;
  INSERT INTO ARAUCANO(CONTENIDO) VALUES (TO_CHAR(v_num));
-- this lines insert the content of each record in table ARAUCANO
  for i in 1..P_CUR.count loop
    INSERT INTO ARAUCANO(CONTENIDO) VALUES (P_CUR(i));
  end loop;
  COMMIT;
END;

in my php i have this:

$conn = oci_connect('ALUM_INT', 'ALUM_INT', 'DB10');
$v_tipo = 'I';
$designaciones = ['1|0317031','2|0480458','3|1925866'];
$categories = oci_new_collection($conn,'ARRAY_DATOS2','SIUC');
foreach ($designaciones as $value) {
    $categories->append($value);
}
$options = array("type_name" => "ARRAY_DATOS2","schema" => "SIUC");
$pdo = DB::getPdo();
    $stmt_rec = $pdo->prepare("begin SIUC.PRUEBA_VARRAY2(:p1,:p2); end;");
    $stmt_rec->bindParam(':p1',  $v_tipo, PDO::PARAM_STR);
    $stmt_rec->bindParam(':p2',  $categories, SQLT_NTY, -1, $options);
    $result = $stmt_rec->execute();
dd($result);

the $result is "true" but in table ARAUCANO is 0, the count of the collection, is 0

select * from araucano; 1 0

System details

ORACLE 12 DB PHP 5.5.1

ok, now check the function in your code

public function bindParam($parameter, &$variable, $dataType = PDO::PARAM_STR, $maxLength = -1, $options = null)

I found this in the type SQLT_NTY

case SQLT_NTY:
                $ociType = SQLT_NTY;
                $schema    = isset($options['schema']) ? $options['schema'] : '';
                $type_name = isset($options['type_name']) ? $options['type_name'] : '';
                // set params required to use custom type.
this line 467 -->         $variable = $this->connection->getNewCollection($type_name, $schema);
                break;

in line 467, overwrite the value of the IN param with a new collection, I test that put this line before and after

echo('<br>->TAMA 1');   
var_dump($variable->size());
  $variable = $this->connection->getNewCollection($type_name, $schema);
echo('<br>->TAMA 2');   
var_dump($variable->size());

the size is 3 and then 0

I replace the code with this

$variable2 = $this->connection->getNewCollection($type_name, $schema);
$variable2->assign($variable);

$variable = $this->connection->getNewCollection($type_name, $schema);

$variable->assign($variable2);

and solve the problem, result

 select * from araucano;
1   3   
2   1|0317031   
3   2|0480458   
4   3|1925866   

this is a patch only for collections, I wait to you for a true solution

sorry by my english

thanks in advance

yajra commented 4 years ago

@barrigapicante thanks for digging this. Can you please send a PR of your findings? Will check this further when I got the chance. Thanks!