第一次接触 Oracle DB 中的 LOB,偶然发现了一些让我感到困惑的东西。
我必须将BLOB插入到要插入表中的行的列中,使用Pro*C
. 文档说我有两种可能的选择。
- 如果它适合缓冲区,则一次全部写入 lob,使用
EXEC SQL WRITE
ONE
如果缓冲区太小,则使用文档中所谓的polling零碎地编写 lob,并由以下 3 个步骤组成:
EXEC SQL WRITE
FIRST
EXEC SQL WRITE
NEXT
n次EXEC SQL WRITE
LAST
但是,我发现我可以将文档中描述的轮询EXEC SQL WRITE
APPEND
方法简单地替换为n+2 次,从而使循环更加简单、直观,并且更容易处理错误处理。
所以,不要写这样的东西(取自文档):
if (filelen > MAXBUFLEN)
nbytes = MAXBUFLEN ;
else
nbytes = filelen ;
fread((void *)buffer, (size_t)nbytes, (size_t)1, fp) ;
remainder = filelen - nbytes ;
if (remainder == 0)
{
EXEC SQL LOB WRITE ONE :amt
FROM :buffer INTO :blob AT :offset ;
}
else
{
EXEC SQL LOB WRITE FIRST :amt
FROM :buffer INTO :blob AT :offset ;
last = FALSE ;
EXEC SQL WHENEVER SQLERROR DO break ;
do
{
if (remainder > MAXBUFLEN)
nbytes = MAXBUFLEN ;
else
{
nbytes = remainder ;
last = TRUE ;
}
if (fread((void *)buffer, (size_t)nbytes, (size_t)1, fp) != 1)
last = TRUE ;
if (last)
{
EXEC SQL LOB WRITE LAST :amt
FROM :buffer INTO :blob ;
}
else
{
EXEC SQL LOB WRITE NEXT :amt
FROM :buffer INTO :blob;
}
remainder -= nbytes ;
}
while (!last && !feof(fp)) ;
}
可以这样写:
while ((nbytes = remainder < MAXBUFLEN ? remainder : MAXBUFLEN))
{
if (fread(buffer, nbytes, 1, fp) != 1) {
/* Handle error somehow */
break;
}
EXEC SQL LOB WRITE APPEND :nbytes
FROM :buffer WITH LENGTH :nbytes INTO blob;
remainder -= nbytes;
}
我彻底测试了第二种方法,没有注意到任何问题,所以我想知道:
- 第二种方法有什么问题让我不注意吗?
- 如果可以像第二种方法一样继续进行,那么像文档解释的那样,由 3 个步骤组成的轮询机制需要什么?