似乎oracledb在从数据库中检索BLOB数据的方式不一致,LOB vs Buffer
在将oracledb 3.0.1与nodejs一起使用以通过select语句从Oracle检索blob时,有时将数据作为LOB检索,有时作为Buffer检索。我需要将其始终作为LOB进行检索。
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];
处理blob很困难,因为有时它会作为缓冲区返回,而有时又作为LOB返回,如下所示。
任何想法如何使其始终作为另一个(最好是作为LOB)返回。
有时会将blob作为缓冲区提供:
<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] }
答案 0 :(得分:0)
该行为不是随机的。作为stated in the doc,BLOB和CLOB都作为Lob类的实例返回。该类实现Node.js stream interface。这对于较大的LOB是必需的,因此您不会在Node.js中缓冲所有内容。有关更多信息,请参见streaming LOBs上的文档部分。
也请参见以下示例:
对于使用相对较小的LOB(例如,几兆字节或更小)和/或较少数量的最终用户的人们来说,流API的开销是不值得的。对于那些人来说,从数据库中完全实现为一个缓冲区(对于BLOB)或作为一个字符串(对于CLOB)获取LOB会容易得多。
在这种情况下,驱动程序提供了多个选项来覆盖默认值:
execute
选项,只会影响正在执行的查询。这是具有“列到类型”映射详细信息的对象。请参见以下示例fetchInfo: