初めて Oracle DB の LOB にアプローチし、困惑したものに出くわしました。
テーブルに挿入する行の列にBLOBを挿入する必要がありますPro*C
。ドキュメントには、2 つの選択肢があると書かれています。
- バッファに収まる場合は、一度にすべてのロブを書き込みます。
EXEC SQL WRITE
ONE
バッファが小さすぎる場合は、ドキュメントでpollingと呼ばれるものを使用して、次の 3 つの手順からなるシーケンスでlob を少しずつ書き込みます。
EXEC SQL WRITE
FIRST
EXEC SQL WRITE
NEXT
n回EXEC SQL WRITE
LAST
しかし、ドキュメントに示されているポーリング方法を単純に n+2 回に置き換えることができることがわかりました。これによりEXEC SQL WRITE
APPEND
、ループがはるかに単純で直感的になり、エラー処理がより簡単になります。
したがって、このようなものを書く代わりに (ドキュメントから取得):
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;
}
問題に気付かずに2番目のアプローチを徹底的にテストしたので、疑問が残りました:
- 私の注意を無視する2番目のアプローチに何か問題がありますか?
- 2 番目のアプローチのように進めても問題ない場合、ドキュメントで説明されているような 3 つのステップからなるポーリング メカニズムの必要性は何ですか?