BLOB случайным образом возвращается как LOB и Buffer - PullRequest
1 голос
/ 20 апреля 2019

Кажется, что oracledb не согласован в том, как он извлекает BLOB-данные из базы данных, LOB против буфера

При использовании oracledb 3.0.1 с nodejs для получения большого двоичного объекта из Oracle с помощью оператора select, иногдаданные извлекаются как большой объект, а иногда как буфер.Мне нужно, чтобы он постоянно извлекался в виде большого объекта.

    let connection = null;

    const connectionAttributes = {
        user: process.env.NODE_OCO_DB_USER,
        password: process.env.NODE_OCO_DB_PASSWORD,
        connectString:  `${process.env.NODE_OCO_DB_HOST}:${process.env.NODE_OCO_DB_PORT}/${process.env.NODE_OCO_DB_SID}`
    };

    connection = await oracledb.getConnection(connectionAttributes);

    const sql = `
                    SELECT 
                        file_size, file_name, file_content 
                    FROM 
                        ocoadmin.oco_level1_attachment 
                    WHERE 
                        pk_id = :pk_id 
                `;

    const bindParams = { 
        pk_id: req.params.attachmentId,
    }

    const result = await connection.execute(sql, bindParams);

    if (result.rows.length === 0) {
        console.error('Error getting row ' + req.params.attachmentId); 
        throw new Error('Error getting row ' + req.params.attachmentId);
    }

    const fileSize = result.rows[0][0];
    const fileName = result.rows[0][1];
    const blob = result.rows[0][2];

Трудно обрабатывать большой двоичный объект, потому что иногда он возвращается в виде буфера, а иногда в качестве большого объекта, как показано ниже.

Любая идея, как сделать так, чтобы он всегда возвращался как один из других, предпочтительно как большой объект.

Иногда большой двоичный объект предоставляется в виде буфера:

<Buffer ff fe 3d 00 3d 00 3d 00 20 00 56 00 65 00 72 00 62 00 6f 00 73 00 65 00 20 00 6c 00 6f 00 67 00 67 00 69 00 6e 00 67 00 20 00 73 00 74 00 61 00 72 00 ... >

Иногда блоб предоставляется в виде LOB:

Lob {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events:
   { end: { [Function: bound onceWrapper] listener: [Function: onend] },
     finish: { [Function: bound onceWrapper] listener: [Function] } },
  _eventsCount: 2,
  _maxListeners: undefined,
  _writableState:
   WritableState {
     objectMode: false,
     highWaterMark: 16384,
     finalCalled: false,
     needDrain: false,
     ending: false,
     ended: false,
     finished: false,
     destroyed: false,
     decodeStrings: true,
     defaultEncoding: 'utf8',
     length: 0,
     writing: false,
     corked: 0,
     sync: true,
     bufferProcessing: false,
     onwrite: [Function: bound onwrite],
     writecb: null,
     writelen: 0,
     bufferedRequest: null,
     lastBufferedRequest: null,
     pendingcb: 0,
     prefinished: false,
     errorEmitted: false,
     bufferedRequestCount: 0,
     corkedRequestsFree:
      { next: null,
        entry: null,
        finish: [Function: bound onCorkedFinish] } },
  writable: true,
  allowHalfOpen: true,
  iLob:
   ILob {
     valid: true,
     autoCloseLob: true,
     type: 2007,
     offset: 1,
     pieceSize: 8060,
     length: 1062462,
     chunkSize: 8060 },
  close: [Function] }

1 Ответ

0 голосов
/ 20 апреля 2019

Поведение не случайно. Как указано в документе , и BLOB, и CLOB возвращаются как экземпляры класса Lob. Этот класс реализует потоковый интерфейс Node.js . Это необходимо для больших больших объектов, поэтому вы не буферизуете все в Node.js. Для получения дополнительной информации см. Раздел документации по потоковым объектам .

Смотрите также эти примеры:

Для людей, которые работают с относительно меньшими большими объектами (скажем, несколькими мегабайтами или менее) и / или меньшим числом конечных пользователей, издержки потокового API не стоят того. Для тех людей получение LOB из базы данных, полностью материализованной как Buffer (для BLOB), для String (для CLOB) намного проще.

В этих случаях драйвер предлагает несколько вариантов переопределения значений по умолчанию:

  1. oracledb.fetchAsBuffer : Это глобальный параметр, который влияет на все запросы. Это может быть использовано для указания того, что BLOB должны быть выбраны как буферы.
  2. oracldb.fetchAsString : это еще один глобальный параметр, который повлияет на все запросы. Его можно использовать для указания того, что CLOB следует извлекать как строки.
  3. fetchInfo : эта опция execute влияет только на выполняемый запрос. Это объект с деталями сопоставления «столбец для ввода».

Смотрите этот пример fetchInfo:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...