Delphi ADO RecordSet BUG?

Delphi6,7提供ADO RecordSet的LoadFromFile和SaveToFile方法
与Xml交互:

procedure LoadFromFile(const FileName: WideString);

Description

Call LoadFromFile to load the recordset for the calling ADO dataset component from a file. If the loading operation fails, the current recordset is neutralized (set to nil), the dataset component remains inactive, and an EOleException exception is raised. If the attempt to load data from a file is successful, the ADO dataset component is automatically activated and the data made available.

FileName is a string containing the name of the file.

LoadFromFile closes the dataset component before loading the recordset from the file specified in FileName.

其xml文档编码格式要求为utf8:

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
    <s:Schema id="RowsetSchema">
        <s:ElementType name="row" content="eltOnly" rs:updatable="true">
            <s:AttributeType name="C01" rs:number="1" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8195" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C02" rs:number="2" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="F01" rs:number="3" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="float" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="F02" rs:number="4" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="float" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="F03" rs:number="5" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="float" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="SPROJID" rs:number="6" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="IDEGREE" rs:number="7" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="float" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C03" rs:number="8" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C04" rs:number="9" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C05" rs:number="10" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C06" rs:number="11" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="C07" rs:number="12" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
            <s:AttributeType name="SPLANNAME" rs:number="13" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="Memo" dt:maxlength="8100" rs:maybenull="True" />
            </s:AttributeType>
        </s:ElementType>
    </s:Schema>
    <rs:data>
        <z:row C01="81007CB607600" C02="苛刻环境下润滑抗磨材料的基础研究" F01="0" F02="0" F03="0" SPROJID="008100081007CB076001" IDEGREE="81006001" C03="中国科学院兰州化学物理研究所" C04="刘维民" C05="刘维民" C06="马建华" SPLANNAME="国家重点基础研究发展计划" />
    </rs:data>
</xml>

而.Net处理xml具有先天的优势,于是我们当前系统采取web service传递xml与Delphi客户端交互

问题就出在上述xml中的dt:maxlength上
该属性描述字段最大长度(文本字段有效)
而使用ADO.Net OleDb Provider For Oracle获取的ADO.Net DataSet表格式中DataColumn不包含有效的MaxLength属性(一直为-1)
这样hack dom后变成:
 <s:AttributeType name="C07" rs:number="12" rs:writeunknown="true" rs:baseCatalog="TBRDB0" rs:baseTable="TBRDB0" rs:keycolumn="False" rs:autoincrement="False">
                <s:datatype dt:type="string" dt:maxlength="-1" rs:maybenull="True" />
            </s:AttributeType>

在D6中RecordSet.LoadFromFile后,RS中数据是存在的,但rs.FieldByName('C07').ToString Throw a Error

手工改变xml文件,将dt:maxleng配置为10,没有错误,但该字段被截取成10位长度了

看来只需在.Net端生成xml时将dt:maxleng配置得足够大
然而很不幸,dt:maxleng>8200+时(具体为多少没测试,当时急着改BUG)
出现问题和dt:maxleng=-1一样

看来只有使用小于8000的文本了


原文地址:https://www.cnblogs.com/calmzeal/p/530958.html