oracle数据库导出rtf,Delphi中对Oracle存取RTF文档

Delphi中对Oracle存取RTF文档以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

9d3ec559ec146181dff425446a7e6616.png

关系数据库都提供大文档的存储和提取 对于视频资料 音频资料 图象资料等大文档 一般需要另外开辟字段用于存储摘要信息 因此在查询和检索时并不访问大字段 而只是在存储和提取时才操作 大字段 例如 你不能对Oracle中的LONG RAW类型进行LIKE介词的查询 更不能使用等号 = 查询 这对于存储大段文本(容量超过 K)同时又需要全文检索是相当不便的 本文将介绍如何利用数据库的字符串数据类型存取和查询大段文本 这里以Oracle数据库和Delphi应用程序为例 重点介绍如何在数据库中存取 RTF文档

对于纯文本 可以简单地将其分割成若干个串 分别存储到VARCHAR( )字段中即可 在查询时可以使用LIKE比较 从而达到全文检索的目的 为了保留换行等段落信息 应当将回车换行(# # )也作为串的一部分进行保存 数据录入时可以提供Memo控件(不是DBMemo)进行录入 然后顺序连接各行 当连接成的串临近 个字符(单字节字符)长度时 就存入一条记录 然后对剩余的行重复上述操作 这样 最终将纯文本存成若干长度不超过 的VARCHAR( ) 字段中 这里需要另外开辟字段 用于存储文本编号和子序号 以便区分不同的文本和读取文本时顺序连接所有的子串 查询纯文本时 就可以象查询普通的VARCHAR 字段一样 可以使用LIKE 也可以使用等号 = (几乎不需要使用) 需要注意的是 可能用户提供的关键字正好被存储在不同的子串中 这时是查询不到的 因此 在设计时应当考虑存储重复的串 例如 每个子串中仅有前 个字符是有效字符 最后 个字符用于存储 下一个子串的前 个字符 这样就避免了关键字被分开的情况 唯一的不足是 必须限制用户输入的查询关键字长度不得超过 个字符( 个汉字) 但这很正常 算不上不足

事实上 同样可以利用这一技巧对 RTF文档进行存取和查询 这时 用于录入和显示 RTF文档的是 RichEdit控件(不是DBRichEdit) 而不再是Memo控件 对于 RTF文档的存取 不能象存取纯文本那样通过Memo的属性Lines Strings[Index]进行操作(尽管RichEdit控件具有相同的属性) 因为这样做就无法保存文档的格式了 需要利用的是RichEdit的两个方法 SaveToFile和LoadFromFile 需要了解的 是 RTF文件中用纯字符描述字体 字号 文本等各种格式信息和内容信息 因此 存储和提取时可以视为纯文本进行操作 但对于查询 就不能直接用LIKE加关键字的方式进行 因为 RTF文档中的每一个汉字都是用特殊的表示方法存储 只有单字节字符是原样存储 所以在查询时要对关键字进行处理才能 用在查询语句中

在测试这个例子之前 必须有如下的数据结构 这里以Oracle创建表的 SQL语句形式给出

(*    CREATE TABLE TEST( { 表名为 TEST }    DOCID NUMBER NOT NULL { 文档编号 }    DOCNAME VARCHAR( ) NOT NULL { 文档标题 }    SUBID NUMBER NOT NULL { 文档子编号 }    TEXT VARCHAR( ) NOT NULL { 子文档内容 }    PRIMARY KEY(DOCID SUBID)); { 联合主键 }    *) 下面是程序实例中的主要部分

{ }

const    BufSize = ; { 串的最大容量 }

type    TBuffer = array [ BufSize] of Char; { 串缓存 }    TFileOfChar = file of Char; { 字符类型文件 }

TChnChar = string[ ]; { 汉字字符类型 }

{ SQL查询 返回首记录首字段的值 }    function SelectSQL(S: string): Variant;    begin    Result := NULL;    with TADOQuery Create(Application) do try    Connection := FMain ADOConnection ;    SQL Append(S);    SQL SaveToFile( c:\a txt );    Open;    Result := Fields[ ] AsVariant;    finally    Free;    end;    end;

{ 下面的函数将RTF文档存入数据库 }    function RTFToDB(ARichEdit: TRichEdit; { 文档容器 }    DocName: string; { 文档标题 }    ATable: TADOTable { 操作的表 }    ): Boolean; { 返回类型 }    const    TmpFileName = c:\x rtf ; { 临时文档 }    var    DocID SubID L: Integer; { 局部变量 }    S: string; { 串 }    F: TFileOfChar; { 字符文件 }    Buf: TBuffer; { 文本缓存 }    begin    ARichEdit Lines SaveToFile(TmpFileName);{ 先存入文件 }    AssignFile(F TmpFileName); { 打开文件 }    Reset(F);    try    DocID := { 产生新的文档编号 }    SelectSQL( SELECT NVL(MAX(DOCID) + ) FROM TEST );    with ATable do if not Active then Active := True;{ 确认表打开 }    SubID := ; { 初始化子编号 }    while not EOF(F) do begin    Inc(SubID);    BlockRead(F Buf BufSize L); { 读取两千个字符 }    S := Buf;    SetLength(S L); { 取实际读取到的字节数 }    with ATable do begin { 增加一条子文档 }    Append;    FieldByName( DOCID ) AsInteger := DocID;    FieldByName( DOCNAME ) AsString := DocName;    FieldByName( SubID ) AsInteger := SubID;    FieldByName( TEXT ) AsString := S;    Post;    end;    end;    Result := True; { 存储成功 }    except    Result := False;{ 存储失败 }    end;    CloseFile(F); { 关闭文件 }    DeleteFile(TmpFileName);{ 删除文件 }    end;

{ 下面的函数从数据库中读取RTF文档 并在指定的容器中显示 }    function RTFFromDB(ARichEdit: TRichEdit;{ RTF文档容器 }    DocName: string; { 文档标题 }    AQuery: TADOQuery { 操作的数据集 }    ): Boolean; { 返回类型 }    const    TmpFileName = c:\temp\x rtf ; { 临时文件 }    var    S: string; { 局部串变量 }    F: TFileOfChar; { 字符文件 }    Buf: TBuffer; { 串缓存 }    I L: Integer; { 局部变量 }    begin    ARichEdit Clear; { 清除当前显示的内容 }    AssignFile(F TmpFileName); { 关联文件 }    try    Rewrite(F); { 打开文件 准备写入从数据库读出的数据 }    with AQuery do begin    Active := False; { 关闭数据集 }    SQL Clear; { 重建SQL语句 }    SQL Append( SELECT SUBID TEXT FROM TEST WHERE DOCNAME = +    DocName + ORDER BY SUBID );    Open; { 打开数据集 }    if RecordCount <> then begin { 确认数据集非空 }    First; { 移到首记录 子文档 }    repeat { 读出一条子文档并写入文件 }    S := FieldByName( TEXT ) AsString;    L := Length(S);    for I := to L do Buf[I] := S[I];    BlockWrite(F Buf L);    Next;    until EOF;    end;    end;    CloseFile(F);{ 关闭文件 }    ARichEdit Lines LoadFromFile(TmpFileName);{ 从文件中装入RTF文档 }    Result := True; { 读取成功 }    except { 读取失败 }    try CloseFile(F); except end;    Result := False;    end;    DeleteFile(TmpFileName); { 删除临时文件 }    end;

{ 下面的函数将汉字单字转换成RTF中表示的形式 }    { 如表示汉字 国 的是ASCII(b )和ASCII(fa) 这里是十六进制 }    { 那么在 RTF文件中对 国 字的表示占用了 个字节 }    { \ b \ fa }    { 因此 需要在查询之前进行转换 由于表示方法中含有Delphi用于 }    { 字符串的分解符 单撇号 因此在转换时需要考虑这一点 }    { 否则就不能构造出正确的 SQL查询语句 }    function ChnCharToRTFCode(Ch: TChnChar): string;    var    C C : Char;    O O : Byte;    S: string;    begin    C := Ch[ ];    C := Ch[ ];    O := Ord(C );    O := Ord(C );    S := Format( \ % X [O ]) + Format( \ % X [O ]);    Result := Lowercase(S);{ 转换为小写 }    end;

{ 根据需要检索的关键字转换成LIKE中使用的串 }    { 这里用于区别汉字的方法是根据编码 }    { 按照Windows 中的双字节编码规则 对于双字节字符 }    { 如汉字字符 是由两个字节构成 其中第一个字节是 }    { 引导字符 汉字引导字符的ASCII 码大于 因此 }    { 可以根据此特点来区分汉字和单字节字符 }    function MakeLikeRTFString(StrToFind: string): string;    var    I: Integer;    ChnChar: TChnChar;    S: string;    begin    S := ;    I := ;    while I < Length(StrToFind) do begin    Inc(I);    if Integer(StrToFind[I]) >= $ then begin{ 汉字的首字节一定不小于 }    ChnChar := StrToFind[I] + StrToFind[I + ];    Inc(I);    S := S + ChnCharToRTFCode(ChnChar);    end else begin{ 单字节字符 }    S := S + StrToFind[I];    if StrToFind[I] = then S := S + StrToFind[I];{ 单撇号的特殊处理 }    end;    end;    Result := S;    end;

{ 构造对关键字进行全文检索的查询语句 }    function MakeLikeString(StrToFind: string): string;    var    S: string;    begin    S := MakeLikeRTFString(StrToFind);    S := SELECT DISTINCT DOCNAME FROM TEST WHERE TEXT LIKE % + S + % ;    Result := S;    end; lishixinzhi/Article/program/Oracle/201311/18394

分页:123

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值