其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

DELPHI基础教程:开发Delphi对象式数据管理功能(二)[3]


发布日期:2023年07月13日
 
DELPHI基础教程:开发Delphi对象式数据管理功能(二)[3]

方法中用到的DbiOpenBlob函数是BDE的API函数该函数用于打开数据库中的BLOB字段

最后如果方法传入的Mode参数值为bmWrite就调用Truncate将当前位置指针以后的

数据删除

分析这段源程序不难知道

● 读写BLOB字段不允许BLOB字段所在DataSet部件有Filter否则产生异常事件

● 要读写BLOB字段必须将DataSet设为编辑或插入状态

● 如果BLOB字段中的数据作了修改则在创建BLOB 流时不再重新调用DBiOpenBlob函数而只是简单地将FOpened置为True这样可以用多个BLOB 流对同一个BLOB字段读写

Destroy方法释放BLOB字段和为FBuffer分配的缓沖区其实现如下

destructor TBlobStreamDestroy;

begin

if FOpened then

begin

if FModified then FFieldFModified := True;

if not FFieldFModified then

DbiFreeBlob(FDataSetHandle FRecord FFieldNo)

end;

if FBuffer <> nil then FreeMem(FBuffer FDataSetRecordSize)

if FModified then

try

FFieldDataChanged;

except

ApplicationHandleException(Self)

end;

end;

如果BLOB流中的数据作了修改就将FField的FModified置为True;如果FField的Modified为False就释放BLOB字段如果FBuffer不为空则释放临时内存最后根据FModified的值来决定是否启动FField的事件处理过程DataChanged

不难看出如果BLOB字段作了修改就不释放BLOB字段并且对BLOB 字段的修改只有到Destroy时才提交这是因为读写BLOB字段时都避开了FField而直接调用BDE API函数这一点是在应用BDE API编程中很重要即一定要修改相应数据库部件的状态

Read和Write方法的实现

Read和Write方法都调用BDE API函数完成数据库BLOB字段的读写其实现如下

function TBlobStreamRead(var Buffer; Count: Longint) Longint;

var

Status: DBIResult;

begin

Result := ;

if FOpened then

begin

Status := DbiGetBlob(FDataSetHandle FRecord FFieldNo FPosition

Count @Buffer Result)

case Status of

DBIERR_NONE DBIERR_ENDOFBLOB:

begin

if FFieldFTransliterate then

NativeToAnsiBuf(FDataSetLocale @Buffer @Buffer Result)

Inc(FPosition Result)

end;

DBIERR_INVALIDBLOBOFFSET:

{Nothing};

else

DbiError(Status)

end;

end;

end;

Read方法使用了BDE API的DbiGetBlob函数从FDataSet中读取数据在本函数中各参数的含义是这样的FDataSetHandle代表DataSet的BDE句柄FReacord表示BLOB字段所在记录FFieldNo表示BLOB字段号FPosition表示要读的的数据的起始位置Count表示要读的字节数Buffer是读出数据所占的内存Result是实际读出的字节数该BDE函数返回函数调用的错误状态信息

Read方法还调用了NativeToAnsiBuf进行字符集的转换

function TBlobStreamWrite(const Buffer; Count: Longint) Longint;

var

Temp: Pointer;

begin

Result := ;

if FOpened then

begin

if FFieldFTransliterate then

begin

GetMem(Temp Count)

try

AnsiToNativeBuf(FDataSetLocale @Buffer Temp Count)

Check(DbiPutBlob(FDataSetHandle FRecord FFieldNo FPosition

Count Temp))

finally

FreeMem(Temp Count)

end;

end else

Check(DbiPutBlob(FDataSetHandle FRecord FFieldNo FPosition

Count @Buffer))

Inc(FPosition Count)

Result := Count;

FModified := True;

end;

end;

Write方法调用了BDE API的DbiPutBlob函数实现往数据库BLOB字段存储数据

该函数的各参数含义如下

调用函数DbiPutBlob的各传入参数的含义

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

参数名 含义

──────────────────────────────

FDataSetHandle 写入的数据库的BDE句柄

FRecord 写入数据的BLOB字段所在的记录

FFieldNo BLOB字段号

FPosition 写入的起始位置

Count 写入的数据的字节数

Buffer 所写入的数据占有的内存地址

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

方法中还根据FField和FTransliterate的值判断是否进行相应的字符集转换最后移动BLOB流的位置指针并将修改标志FModified置为True

Seek和GetBlobSize方法的实现

Seek方法的功能主要是移动BLOB流的位置指针GetBlobSize方法是私有的在Seek方法中被调用其功能是得到BLOB数据的大小它们的实现如下

function TBlobStreamGetBlobSize: Longint;

begin

Result := ;

if FOpened then

Check(DbiGetBlobSize(FDataSetHandle FRecord FFieldNo Result))

end;

function TBlobStreamSeek(Offset: Longint; Origin: Word) Longint;

begin

case Origin of

: FPosition := Offset;

: Inc(FPosition Offset)

: FPosition := GetBlobSize + Offset;

end;

Result := FPosition;

end;

GetBlobSize调用了BDE API的DbiGetBlobSize函数该函数的参数的含义同前面的API函数相同

[] [] [] []

               

上一篇:DELPHI基础教程:开发Delphi对象式数据管理功能(二)[4]

下一篇:DELPHI基础教程:开发Delphi对象式数据管理功能(二)[2]