T-SQL数据类型的细微差别(三)

BLOB型:
SQL Server通过image和text(及ntext)数据类型来支持BLOB(二进制大对象)字段,这些数据类型允许存储和检索大到2GB的字段。BLOB字段存在一个单独的页链表中。BLOB列本身只存在一个十六位二进制的指针,指向该列的页链表的第一页,不能将文本或图像定义成局部变量。可以把文本和图像作为一个参数传给存储过程,然后就可以在DML语句中使用它们,不可以重新赋值给变量,也可以进行其他操作。在WHERE语句中,不能用符号指向BLOB列-可用谓词LIKE,PARINDEX()或DATALENGTH()来代替等号,例如:
CREATE TABLE  #testnotes (K1 int identity, notes text)
INSERT #testnotes (notes) VALUES ('test')
GO
SELECT * FROM # testnotes WHERE notes = 'text'
GO
DROP TABLE #testnotes
GO
尽管 INSERT语句可以给text赋值,但是SELECT语句不能用传统方法查询出text值,必须用这样的方法:
SELECT * FROM #testnotes WHERE notes LIKE 'text'
BOLB型数据的检索:
不能通过简单的SELECT语句返回大的BLOB数据,尽管可用SET TEXTSIZE来控制SELECT语句返回的文本量,但是这种方法不能正确处理大量的BLOB数据,并且因为不能定义局部的文本和图像变量,所以不能用SELECT语句把BLOB赋值给需要进一步分解的变量。但是可用READTEXT命令来分段地存取BLOB数据。该命令有四个参数:被读取的列,指向潜在文本的有效指针,读取的起始点偏移量,每次读取的块大小,使用TEXTPTR()函数可以检索到BLOB列潜在数据的指针。该指针为16位二进制的值,指向BLOB数据的第一页。可以用函数TEXTVALID()来检验指针是否有效。例如:
DECLARE @textptr binary(16)
BEGIN TRAN
SELECT @textptr = TEXTPTR(pr_info)
FROM pub_info (HOLDLOCK)
WHERE pub_id = '1389'
READTEXT pub_info.pr_info @textptr 29 20
COMMIT TRAN
例中使用了事务处理和关键词HOLDLOCK,以保证从第一次检索开始到READTEXT的整个过程中指针的精确性.因为在存取过程中有可能有其他的用户修改BLOB列.所以在初始化读完到调用READTEXT之间.TEXTPTR返回的指针无效了,使用事务处理就可以确保这种事情不会发生.人们可能认为事务处理就是限制数据被修改的管理,但是除了这些功能之外,使事务处理还可以有效地确保阅读的可能性.
并不是指定固定的偏移量和读取长度.而是常用PATINDEX()函数来在BLOB字段中查找子字符串并读出,用法如下:
DECLARE @textptr binary(16), @patindex int ,@patlength int
BEGIN TRAN
SELECT @textptr = TEXTPTR(pr_info), @patindex = PATINDEX('%Algodata Infosystems%', pr_info) - 1, @patlength = DATALENGTH('Algodata Infosystems') FROM pub_info(HOLDLOCK)
WHERE PATINDEX('%Algodata Infosystems%', pr_info) <> 0
READTEXT pub_info @textptr @patindex @patlength
COMMIT TRAN
BLOB型数据的修改:
提供给BLOB的列小于或等于8000个字段的文本或图像,是与修改其他类型的列一样最直接的方法.与其他类型的数据一样,可用INSERT, UPDATE和DEFAULT约束来给这些列赋值,例如:
CREATE TABLE #testnotes (K1 int identity, notes text DEFAULT SPACE(10))
INSERT #testnotes DEFAULT VALUES
INSERT #testnotes (notes) VALUES (REPLICATE('x', 20))
UPDATE  #testnotes SET notes = REPLICATE('y', 10) WHERE K1 = 1
SELECT * FROM #testnotes
DROP TABLE #testnotes
如果要写入超过8000字节的数据,T-SQL就要求用命令UPDATETEXT或WRITETEXT.
UPDATETEXT可以修改BLOB的字段的一部分,而WRITETEXT则将所有内容都重写.
CREATE TABLE #testnotes (K1 int identity, notes text DEFAULT REPLICATE('x',20))
BEGIN TRAN
INSERT #testnotes DEFAULT VALUES
DECLARE @textptr binary(16)
SELECT @ttextptr = TEXTPTR(notes) FROM #testnotes(UPDLOCK)
UPDATETEXT #testnotes.notes @textptr 0 0 '222'
SELECT * FROM #testnotes
COMMIT TRAN
GO
DROP TABLE #testnotes
注意UPDATETEXT和WRITETEXT都需要一个有效文本的指针,所以不能用它们来向空的BLOB字段来写数据.
这就使向一个新行插入数据比较困难.最好的办法就是为BLOB列设置DEFAULT约束,然后当表中新增加一行的时候,列接受到一个有效值,可通过单独的TEXTPTR()查询对其进行访问.一旦有了有效文本指针,就可以调用UPDATETEXT 或WRITETEXT来向BLOB列插入数据.

以上内容是《Transact-SQL权威指南》一书的读书笔记,感谢作者KEN HENDERSON 和 译者 健莲科技 中国电力出版社 为我带来这么经典的T-SQL书籍。
posted @ 2006-12-19 21:03  斯伯内德  阅读(934)  评论(1编辑  收藏  举报