PHP oci insert для возврата дескриптора BLOB и ключа записи - PullRequest
0 голосов
/ 30 октября 2019

Я использую Oracle oci в PHP. Попытка реализовать запрос вставки для хранения дочерней записи документа / файла (с BLOB для содержимого) и возврата ключа записи для сохранения в родительской записи. Я надеялся, что смогу использовать возвращающее предложение для возврата как дескриптора BLOB (стандартная практика) для хранения содержимого, так и ключа записи для возврата ключа записи (который устанавливается с помощью последовательности и срабатывания триггера при отсутствиизначение передается ключу). Во всяком случае, я получаю сообщение об ошибке для привязки переменной записи ключа записи (запрашивая дескриптор). Я просто пытаюсь сделать слишком много в одном запросе?

Код выглядит следующим образом:

Во-первых, метод построения и отправки вызова вставки файла:

function insert_file($fcontents, $ftype, $fname, $fsize) {
    $sql="INSERT INTO ES_FILE (FILE_TYPE,FILE_NAME,FILE_CONTENTS,".
    "FILE_SIZE) ".
    "VALUES (?, ?, EMPTY_BLOB(), ?)";
    $fseq=$this->ora_lob_insert($sql,array($ftype, $fname, $fsize),
        'FILE_CONTENTS',$fcontents,'FILE_KEY');
    return $fseq;
}

Далее стандартный метод для вставки записей, содержащих BLOB. Передается строка запроса вставки, массив значений переменных связывания, имя столбца BLOB, содержимое BLOB и теперь имя другого столбца, который должен быть возвращен (в конечном счете, как возвращаемое значение метода (если оноЭтот метод был хорошо протестирован, прежде чем я добавил дополнительную функцию дополнительного возвращаемого столбца / значения ...

public function ora_lob_insert($sql,$bindarr=array(),$lobcol='',$lobvar='',$other_retcol='') {
    Global $errormess;
    $retcol=0;
    // $sql must finish "RETURNING {lob_column} INTO :mylob" - Use EMPTY_CLOB() when inserting
    if (substr_count($sql,'?') != count($bindarr))
    { // number of ? in query string different to number of values in array
        $errormess='Error ora_bind_exec: Mismatch between query markers and bind values array!';
    }
    $i=0;
    $worked=false;
    foreach ($bindarr as $bindvar) {
        $sql=preg_replace('/\?/',":var${i}", $sql, 1);
        $i++;
    }
    if (!strcmp($other_retcol,'')) {
        $sql.=" RETURNING $lobcol INTO :mylob";
    } else {
        $sql.=" RETURNING $lobcol, $other_retcol INTO :mylob, :retcol";
    }
    $obf_parse=@oci_parse($this->connect,$sql);
    if ($obf_parse === false)
    { // Parse Failed
        $errormess='Error ora_lob_insert: Query Parse Failed!';
    }
    $myLOB = @oci_new_descriptor($this->connect, OCI_D_LOB);
    // Bind the returned Oracle LOB locator to the PHP LOB object
    @oci_bind_by_name($obf_parse, ":mylob", $myLOB, -1, OCI_B_BLOB);
    if (strcmp($other_retcol,'')) {
        oci_bind_by_name($obf_parse, ":retcol", $retcol, -1, OCI_B_BLOB);
    }
    $i=0;
    foreach ($bindarr as $bindvar) {
        @oci_bind_by_name($obf_parse,":var${i}",$bindarr[$i],-1);
        $i++;
    }
    $list=array();
    $obf_exec=@oci_execute($obf_parse,OCI_DEFAULT);
    if ($obf_exec === false)
    { // Execute Failed
        $errormess='Error ora_lob_insert: Query Execution Failed!'."($sql)";
    }
    // Now save a value to the LOB
    if ( !$myLOB->save($lobvar)) {
        // On error, rollback the transaction
        oci_rollback($this->connect);
        $errormess='Error ora_lob_insert: Failed savin BLOB!';
    } else {
        // On success, commit the transaction
        oci_commit($this->connect);
        $worked=true;
    }

    @oci_free_statement($obf_parse);
    if (!strcmp($other_retcol,'')) {
        return $worked;
    } else {
        return $retcol;
    }

}

При запуске строка, выполняющая имя oci_bind_by_name для "retcol", даетОшибка PHP и сообщение «Невозможно найти свойство дескриптора ...».

Документация предлагает использовать только дескрипторы для обработки BLOB и FILE.

Я просто ломаю библиотеки oci, пытаясь что-то сделатьслишком сложный?

...