Хранимая процедура оракула, вызванная в цикле for из PHP, работает только для последней итерации - PullRequest
1 голос
/ 14 марта 2019

У меня есть хранимая процедура в php для обработки некоторых данных. Вот как я это называю:

$listeDeNdi= $_POST['LISTEDENDI'];
    $ndiTable=split("\n", $listeDeNdi);
    $calibreLongueur= $_POST['CALIBRELONGUEUR'];
    $validit=$_POST['VALIDITE'];

$sql="DECLARE
              PI_NDI NUMBER;
              PI_VALIDITE NUMBER;
              PI_CALIBRE_LONGUEUR VARCHAR2(32767);
              PO_CODE_ERR NUMBER;
              PO_LIB_ERR VARCHAR2(32767);

              BEGIN
              ARIANE_ADMIN.P_FORCE_ELIGIBILITE ( :PI_NDI, :PI_VALIDITE, :PI_CALIBRE_LONGUEUR, :PO_CODE_ERR, :PO_LIB_ERR );
              END;";

$stid = oci_parse($conn, $sql);
for ( $i=0;$i<count($ndiTable); $i++){
    $binds = [
    ':PI_VALIDITE'=> $validit,
    ':PI_CALIBRE_LONGUEUR'=> $calibreLongueur,
    ':PI_NDI'=> $ndiTable[$i],
    ':PO_CODE_ERR'=> $PO_CODE_ERR,
    ':PO_LIB_ERR'=> $PO_LIB_ERR,
    ];

    foreach ($binds as $key => $val){
      if($key === ':PO_CODE_ERR'){
       oci_bind_by_name($stid, $key, $binds[$key],40);
       } else if ($key === ':PO_LIB_ERR'){
         oci_bind_by_name($stid, $key, $binds[$key], 32767 , SQLT_CHR);
         }else {
          oci_bind_by_name($stid, $key, $binds[$key]);
          }
      }
    oci_execute($stid);
    echo "For NDI ".$ndiTable[$i]." :<br> ";
    echo "PO_LIB_ERR : ".$binds[':PO_LIB_ERR'];
    echo "<br>";
    echo "PO_CODE_ERR : ".$binds[':PO_CODE_ERR'];
    echo "<br>";
    $code[$i]=$binds[':PO_CODE_ERR'];
    $lib[$i]=$binds[':PO_LIB_ERR'];

}
foreach($code as $i){
 echo $code[$i]."<br>";
 echo "hi<br> ";
 }

foreach($lib as $i){
 echo $lib[$i]."<br>";
 echo "hi<br> ";
 }

Я получаю список телефонных номеров из формы, и я вызываю процедуру один раз для каждого элемента этого списка, как вы можете видеть в цикле for в приведенном выше коде.

Работает нормально, когда список содержит только один элемент, но когда список содержит более одного, кажется, что только последняя итерация заполняет мои параметры PO_CODE_ERR и PO_LIB_ERR.

Я искал и обнаружил, что это может быть проблема с функцией oci_bind_by_name и loop, как сказано в руководстве php :


Аргумент переменной PHP является ссылкой. Некоторые формы циклов не работают должным образом:

<?php
foreach ($myarray as $key => $value)  {
oci_bind_by_name($stid, $key, $value);
}
?>    

Это связывает каждый ключ с местоположением $ value, поэтому все связанные переменные в конечном итоге указывают на значение последней итерации цикла. Вместо этого используйте следующее:

<?php
foreach ($myarray as $key => $value) {
oci_bind_by_name($stid, $key, $myarray[$key]);
}
?>    

Однако я не уверен, как это относится к моему делу и как его решить. Любая помощь будет оценена. Большое спасибо!


Редактировать: добавление отпечатков, которые я не указал, и результатов, полученных от них:

Если в списке только один элемент:

Для NDI 987987987:
PO_LIB_ERR: ERREUR: AUCUNE INFO SUR CE NDI DANS LE CACHE ARIANE
PO_CODE_ERR: 1

Если в списке более одного элемента:

Для NDI 987987987:
PO_LIB_ERR:
PO_CODE_ERR:
Для NDI 654654654:
PO_LIB_ERR:
PO_CODE_ERR:
Для NDI 321321321:
PO_LIB_ERR: ERREUR: AUCUNE INFO SUR CE NDI DANS LE CACHE ARIANE
PO_CODE_ERR: 1


Edit2: я попытался сохранить параметры PO_LIB_ERR и PO_CODE_ERR в двух массивах и распечатать их после цикла for (см. Код выше). Хотя я могу видеть результаты, напечатанные в цикле for, я не могу видеть их в моих новых массивах, они просто отображают пустые строки, когда я их повторяю.

Вот так:

Для NDI 787778781:
PO_LIB_ERR: ERREUR: AUCUNE INFO SUR CE NDI DANS LE CACHE ARIANE
PO_CODE_ERR: 1

привет

привет

1 Ответ

0 голосов
/ 18 марта 2019

Через некоторое время мы нашли решение с помощью oci_error для печати любого сообщения об ошибке, которое пришло бы от oci_execute.

Оказалось, что наши номера телефонов были строками, а не целыми числами, поэтому oracle возвращал эту ошибку:

ошибка числового значения или значения: ошибка преобразования символа в число ORA-06512

нам просто нужно было преобразовать наш массив телефонных номеров в отображение:

$binds = [
    ':PI_VALIDITE'=> $validit,
    ':PI_CALIBRE_LONGUEUR'=> $calibreLongueur,
    ':PI_NDI'=>(int)$ndiTable[$i],
    ':PO_CODE_ERR'=> $PO_CODE_ERR,
    ':PO_LIB_ERR'=> $PO_LIB_ERR
    ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...