0

第一次接触 Oracle DB 中的 LOB,偶然发现了一些让我感到困惑的东西。

我必须将BLOB插入到要插入表中的行的列中,使用Pro*C. 文档说我有两种可能的选择。

  1. 如果它适合缓冲区,则一次全部写入 lob,使用EXEC SQL WRITE ONE
  2. 如果缓冲区太小,则使用文档中所谓的polling零碎地编写 lob,并由以下 3 个步骤组成:

    1. EXEC SQL WRITE FIRST
    2. EXEC SQL WRITE NEXTn次
    3. 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;
}

我彻底测试了第二种方法,没有注意到任何问题,所以我想知道:

  1. 第二种方法有什么问题让我不注意吗?
  2. 如果可以像第二种方法一样继续进行,那么像文档解释的那样,由 3 个步骤组成的轮询机制需要什么?
4

1 回答 1

0

如果与使用 LBS(LOB 缓冲子系统)的适当缓冲一起使用,可能会有一些优势。甲骨文解释说——

缓冲具有以下优点,尤其是对于客户端上对 LOB 的特定区域执行许多小型读取和写入的应用程序:

  1. LBS 减少了到服务器的往返行程,因为您使用对 LOB 的多次读取/写入填充缓冲区,然后在执行 FLUSH 指令时写入服务器。

  2. 缓冲还减少了服务器上的 LOB 更新总数。这可以创建更好的 LOB 性能并节​​省磁盘空间。

滚动到LOB Buffering Subsystem链接中的部分以了解更多信息。

于 2012-10-04T14:23:39.577 回答