检测 empty/filled TBlobField 失败
Detecting empty/filled TBlobField fails
我有一个 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
) 这个值仍然是真.
我也尝试检查属性 Size
、DataSize
、BlobSize
,它们都是 0.
如何检查我的 TBlobField 是否包含数据?
(或者我在这段代码中做错了什么?)
* 原因:我们不想把所有这些数据都拉进来;实际上加载带有许多 blob 的 TClientDataSet
会在我们使用的 RemObjects 组件中产生 'package too large' 错误
编辑 1:它可能与字段的内容有关,而不是 'sticking' - 在紧跟在 Post lBlobField.Value
之后的代码的另一部分是空的。
编辑 2:这是一个包含 3 个嵌套 table 查询的数据集。 DataSet
是第三层 TClientDataSet
,这里需要将数据 blob 写入 fkInternalCalc 字段(因此 bmWrite
、Edit 和Post), 仅在实际需要时才使用。 DownLoadAttachmentBlob
通过单独的客户端-服务器通道检索它们。这将获取记录 ID 作为输入并将 blob 数据放入第二个参数 (lBlobStream
)。 (嵌套)数据集包含第 3 级 table(如 ID sExpItmFileID
)的所有其他字段,但不包含其 blob 数据。 DownLoadAttachmentBlob
工作正常。
一旦将 blob 读入 calc 字段,我们希望保留它(而不是检索它两次)。
我会在 SQL 中解决这个问题。
在您的 select 语句中添加一个额外的字段,详细说明 blob 字段是否为空。
select *, ifnull(BlobField, 1, 0) as BlobNull from mytable
现在您可以只查询 BlobNull
字段。显然,您必须调整 IfNull
函数以匹配数据库中可用的语法。
另一种方法可能是将测试用作布尔字段。
select *, (Blobfield is null) as BlobNull from mytable
更好的做法是不要 select 所有字段,而只是拉入所需的字段并使用 where
子句排除填充的 blobfields,但我不确定您的用例是否允许这个。
自己找到了解决方案,这让我很困惑:
必须在调用数据集 Post 方法之前释放 TStream
(var lBlobStream
)。
所以相关代码部分应该是:
Edit;
lBlobStream := CreateBlobStream(lBlobField, bmWrite);
DownLoadAttachmentBlob(FieldByName(sExpItmFileID).Asinteger,lBlobStream);
lBlobStream.Free;
Post;
我有一个 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
) 这个值仍然是真.
我也尝试检查属性 Size
、DataSize
、BlobSize
,它们都是 0.
如何检查我的 TBlobField 是否包含数据?
(或者我在这段代码中做错了什么?)
* 原因:我们不想把所有这些数据都拉进来;实际上加载带有许多 blob 的 TClientDataSet
会在我们使用的 RemObjects 组件中产生 'package too large' 错误
编辑 1:它可能与字段的内容有关,而不是 'sticking' - 在紧跟在 Post lBlobField.Value
之后的代码的另一部分是空的。
编辑 2:这是一个包含 3 个嵌套 table 查询的数据集。 DataSet
是第三层 TClientDataSet
,这里需要将数据 blob 写入 fkInternalCalc 字段(因此 bmWrite
、Edit 和Post), 仅在实际需要时才使用。 DownLoadAttachmentBlob
通过单独的客户端-服务器通道检索它们。这将获取记录 ID 作为输入并将 blob 数据放入第二个参数 (lBlobStream
)。 (嵌套)数据集包含第 3 级 table(如 ID sExpItmFileID
)的所有其他字段,但不包含其 blob 数据。 DownLoadAttachmentBlob
工作正常。
一旦将 blob 读入 calc 字段,我们希望保留它(而不是检索它两次)。
我会在 SQL 中解决这个问题。
在您的 select 语句中添加一个额外的字段,详细说明 blob 字段是否为空。
select *, ifnull(BlobField, 1, 0) as BlobNull from mytable
现在您可以只查询 BlobNull
字段。显然,您必须调整 IfNull
函数以匹配数据库中可用的语法。
另一种方法可能是将测试用作布尔字段。
select *, (Blobfield is null) as BlobNull from mytable
更好的做法是不要 select 所有字段,而只是拉入所需的字段并使用 where
子句排除填充的 blobfields,但我不确定您的用例是否允许这个。
自己找到了解决方案,这让我很困惑:
必须在调用数据集 Post 方法之前释放 TStream
(var lBlobStream
)。
所以相关代码部分应该是:
Edit;
lBlobStream := CreateBlobStream(lBlobField, bmWrite);
DownLoadAttachmentBlob(FieldByName(sExpItmFileID).Asinteger,lBlobStream);
lBlobStream.Free;
Post;