2016-07-26 58 views
2

我有一个fkInternal计算字段ftBlob(在TClientDataSet)包含在DataSnap客户端应用程序中的斑点。检测空/填充TBlobField失败

该字段最初为空,我们只在实际需要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被称为这个值仍然是真的
我也曾尝试检查属性SizeDataSizeBlobSize,他们都为0。

我如何检查我的TBlobField包含数据?
(还是我做错了什么在此代码?)

*原因:我们不想把所有这些数据中;实际上加载TClientDataSet与许多斑点给我们使用的RemObjects组件的'包太大'错误

编辑1:它可能与该字段的内容不“粘” - 在另一部分直接在Post lBlobField.Value后面的代码是空的。

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

+1

很抱歉,如果只是噪音,但你尽管你似乎从中读取创建模式'bmWrite'团块流?此外,不知道'DownLoadAttachmentBlob()'究竟做了什么,blobfield似乎是'ExpItmFileFile',但你将'ExpPItmFileID'传递给函数? –

+0

@TomBrunberg对不起,混淆;-)请参阅编辑2. –

+0

请勿使用*编辑1 *和*编辑2 *乱抛垃圾。通过查看[修订历史记录](http://stackoverflow.com/posts/38588645/revisions),我们可以看到哪个编辑改变了什么。只需编辑帖子并添加详细信息,就好像您将它们写在首位一样。 –

回答

1

找到了解决办法我自己,这完全令我感到困惑:

TStream(VAR lBlobStream)的调用数据集Post方法之前被释放。

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

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

这对我来说并不困难。 TFileStream实际上在写入文件时也会被释放。 –

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,但我不知道你的使用情况允许这一点。

+0

在SQL中解决这个问题的好处是,如果你不打算使用它们,那么你就不需要通过网络来拖动blob,这会加速很多事情。 – Johan