Blob
Blob 就像是 Memo 和 Varbinary 的一个交集:它在一个 FTP 文件中存储二进制数据。跟其它数据类型一样,Microsoft 给 VFP 9 增加 Blob 就是为了给其它数据库提供更好的支持。不过,你很快就可以看到,在 VFP 本地表中它也有很大的用处。Blob 的单字符缩写是“W”。
这里是关于 Blob 的一些细节:
×× Blob 的功能与 Memo 类似:你不能在其上建立索引,它接收 Null 值,在一个表或者游标中的 Blob 字段有一个 2GB 数据的限制(当然了,FPT 文件的总大小也只能有2GB)。在一个 BROWSE 窗口或者 Grid 中,一个 Blob 字段中如果是空的,则显示为 "blob",否则则显示为“Blob”。
×× 你可以使用一个 editbox 或者 MODIFY MEMO 来显示一个 Blob 字段的内容。它的二进制数据以不带前导 0h 的十六进制值的形式显示。然而,它的内容是只读的。在 Blob 字段中的值必须编程的修改,例如REPLACE 或者 GATHER。
×× 跟 Varbinary 一样,在 Blob 字段上是不会进行代码页转换的。
×× 对于 Blob 字段和存储在内存变量中的 Blob 值,TYPE() 和 VARTYPE() 函数返回的是“Q”而不是你准备看到的“W”。DISPLAY/LIST STRUCTURE 和 AFIELDS() 则会正常的为 Blob 字段显示 “Blob”和“W”。
×× TRIM()、RTRIM()、LTRIM()、ALLTRIM()、ALINES()、TRANSFORM()、ISBLANK()、以及 Empty() 对 Blob 的处理跟它们对待 Varbinary 字段是一样的。
×× SQL LIKE 操作符、LIKE()、LIKEC()、BINTOC()、CTOBIN()、以及 APPEND FROM 不支持 Blob 字段。
×× Blob 字段可以被用作包含图像的 General 字段的替代品。General 字段有许多毛病:很难使用、很难更新、体积太大,等等。在一个 General 字段中存储图像需要有一个关联到一个 ActiveX Server 的文件,而存储在一个 Blob 字段中就简单了,它们很容易去更新,跟使用 APPEND GENERAL 不同,你可以使用象下面这样的东西来把一幅图片放入到一个 Blob 字段中去:狐社
replace Picture with filetostr('BobJones.gif') in Employees
要在一个表单上显示存储在一个 Blob 字段中的图像,只要简单的把一个 Image 控件的 PictureVal 属性设置为这个 Blob 字段的内容就行了:
Thisform.imgEmployee.PictureVal = Employees.Picture
运行 BlobDemo.SCX 可以看到这个功能的一个演示。它提供了一个简单的图像浏览器表单。它的 Load 方法会使用下面的代码建立一个用来放图像的游标:
create cursor TEST (FIELD1 Blob) insert into TEST values (filetostr(home() + 'FOX.BMP')) insert into TEST values (filetostr(home() + 'WIZARDS\BANDRPT.BMP')) insert into TEST values (filetostr(home() + 'WIZARDS\WIZFLAX.BMP')) insert into TEST values (filetostr(home() + 'WIZARDS\WIZSTONE.BMP')) insert into TEST values (filetostr(home() + 'WIZARDS\FOXQSTRT.BMP')) go top
表单上的 NEXT 和 Previous 按钮将 Image 控件的 PictureVal 属性设置为游标中的 FIELD1。
为变长的值们指定数据类型
在过去版本的 VFP 中,在一个 SQL SELECT 语句中使用一个表达式会导致变长数据出现一下两种情况中一种:值被填补上空格而不是去掉空格、并且/或所有的值都被剪断到在结果的第一条记录中值的长度了。
这里是从 TestVarcharMapping.PRG 中拿来的一个例子,它演示了这两种问题:
select trim(FirstName) + ' ' + trim(LastName) as FullName ; from Employees ; into cursor Test clear scan ? FullName, len(FullName) endscan use
* 使用一个函数来做,以演示那些字段都被缩放到第一条记录中值的长度了
select GetFullName(FirstName, LastName) as FullName ; from Employees ; into cursor Test scan ? FullName, len(FullName) endscan
function GetFullName(tcFirstName, tcLastName) return trim(tcFirstName) + ' ' + trim(tcLastName)
第一个循环演示了在结果集中的所有记录都被填补空格直到31个字符的长度,即使在 SQL SELECT 语句中的表达式对字段进行过了 Trim。第二个循环演示了所有记录都被裁减到了13个字符的长度,这是因为这个长度是该表达式在第一条记录上的结果的长度;VFP 使用这个值作为这个游标的结构的模板。
无论哪一种行为特性都不是你想要的。在第一种情况中,尽管你要求的是去掉空格的值,可结果还是没有被 Trim 过。在第二种情况中,由于字段的宽度不足以为每条记录包含正确的值,所以数据实际上被丢失了。
|