检测空/填充TBlobField失败

时间:2016-07-26 11:27:08

标签: delphi blob

我有一个fkInternal计算字段ftBlob(在TClientDataSet中),其中包含DataSnap客户端应用程序中的blob。

该字段最初为空,我们只在实际需要blob数据 * 时才填充它。

这是从服务器应用程序中提取数据的代码:

var
  lBlobStream: TStream;
  lBlobField : TBlobField;

with DataSet do
begin
  lBlobField := TBlobField(FieldByName(sExpItmFileFile)); // The fkInternalCalc blob
  try
    // Retrieve the blob stream (calculated field) separately when we don't yet have data:
    if lBlobField.isNull then
    begin
      Edit;
      lBlobStream := CreateBlobStream(lBlobField, bmWrite);
      DownLoadAttachmentBlob(FieldByName(sExpItmFileID).Asinteger,lBlobStream);
      Post;
      ...
    end;

可以很好地检索blob数据 我的问题在于if lBlobField.isNull测试:下次我们进入此代码时(数据集保留在同一记录中,同时不调用ApplyUpdates此值仍然为真< / em>的。
我还尝试检查属性SizeDataSizeBlobSize,它们都是0。

如何检查我的TBlobField是否包含数据?
(或者我在这段代码中做错了什么?)

*原因:我们不想把所有这些数据都拉进来;实际加载带有许多blob的TClientDataSet会在我们使用的RemObjects组件中出现“包太大”错误

编辑1:它可能与字段内容没有“粘贴”有关 - 在帖子lBlobField.Value之后的代码的另一部分是空的。

编辑2:这是一个跨3个嵌套表进行查询的数据集。 DataSet是第三级TClientDataSet,此处数据blob需要写入 fkInternalCalc字段(因此bmWrite,编辑和帖子),只有当他们真正需要时。它们由DownLoadAttachmentBlob通过单独的客户端 - 服务器通道检索。这将记录ID作为输入,并将blob数据放在第二个参数(lBlobStream)中。 (嵌套)数据集包含第3级表的所有其他字段(如ID sExpItmFileID),但不包含其blob数据。 DownLoadAttachmentBlob工作正常。
一旦blob被读入calc字段,我们希望将其保留(不检索两次)。

2 个答案:

答案 0 :(得分:1)

我自己找到了解决方案,这让我很困惑:

在调用Dataset Post方法之前,必须释放TStream(var lBlobStream)。

所以相关的代码部分应该是:

Edit;
lBlobStream := CreateBlobStream(lBlobField, bmWrite);
DownLoadAttachmentBlob(FieldByName(sExpItmFileID).Asinteger,lBlobStream);
lBlobStream.Free;
Post;

答案 1 :(得分:0)

我会在SQL中解决这个问题。

在select语句中添加一个额外字段,详细说明blob字段是否为空。

select *, ifnull(BlobField, 1, 0) as BlobNull from mytable

现在您只需查询BlobNull字段即可。显然,您必须调整IfNull函数以匹配数据库中可用的语法。 另一种方法是将测试用作布尔字段。

select *, (Blobfield is null) as BlobNull from mytable

更好的方法是不选择所有字段,只需拉入所需的字段并使用where子句排除填充的blobfields,但我不确定您的用例是否允许这样做。