CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

用Blob流的办法可以将大量的数据传送到数据库表的BLOB型字段中,SQL语句是如何实现的?

楼主yhec(@_@ 俺是贫农俺怕谁)2003-04-04 08:41:19 在 Delphi / VCL组件开发及应用 提问

对数据库表的操作系统最终都是借助于SQL语句实现的,  
  我们常用BLOB流的办法写BLOB字段以存入图像、文件,  
  系统是如果转换成SQL语句的,比如一个图像有1兆之巨,  
  而SQL语句是一个文本格式,长度有限,如何做到的呢?  
  想了解一下原理  
        100分!  
  问题点数:20、回复次数:8Top

1 楼xiaoxiao197821(你的笑对我很重要)回复于 2003-04-04 08:48:02 得分 2

关注Top

2 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2003-04-04 09:21:38 得分 2

BDE下,可以监控到SQL下语句,做个试验不成  
  BDE+AODBC+ACCESS·)2000Top

3 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2003-04-04 10:26:03 得分 2

是不是对BLOB大字节字段有专门的SQL语句,我曾见过:  
  BLOB I/O:  
   
  STORE   BLOB  
  GET   BLOB   HANDLE  
   
  不知SQL2000SERVER是怎样处理IMAGE字段的?  
  Top

4 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2003-04-04 10:50:10 得分 4

管理   ntext、text   和   image   数据  
  Microsoft®   SQL   Server™   的   ntext、text   和   image   数据类型在单个值中可以包含非常大的数据量(最大可达   2   GB)。单个数据值通常比应用程序在一个步骤中能够检索的大;某些值可能还会大于客户端的可用虚拟内存。因此,在检索这些值时,通常需要一些特殊的步骤。  
   
  如果   ntext、text   和   image   数据值不超过   Unicode   串、字符串或二进制串的长度(分别为   4,000   个字符、8,000   个字符和   8,000   个字节),就可以在   SELECT、UPDATE   和   INSERT   语句中引用它们,其引用方式与较小的数据类型相同。例如,包含短值的   ntext   列可以在   SELECT   语句的选择列表中引用,这与   nvarchar   列的引用方式相同。引用时必须遵守一些限制,例如不能在   WHERE   子句中直接引用   ntext、text   或   image   列。这些列可以作为返回其它数据类型(例如   ISNULL、SUBSTRING   或   PATINDEX)的某个函数的参数包含在   WHERE   子句中,也可以包含在   IS   NULL、IS   NOT   NULL   或   LIKE   表达式中。  
   
  处理较大的数据值  
  但是,如果   ntext、text   和   image   数据值较大,则必须逐块处理。Transact-SQL   和数据库   API   均包含使应用程序可以逐块处理   ntext、text   和   image   数据的函数。  
   
  数据库   API   按照一种通用的模式处理长   ntext、text   和   image   列:    
   
  若要读取一个长列,应用程序只需在选择列表中包含   ntext、text   或   image   列,并将该列绑定到一个程序变量,该变量应足以容纳适当的数据块。然后,应用程序就可以执行该语句,并使用   API   函数或方法将数据逐块检索到绑定的变量中。  
   
   
  若要写入一个长列,应用程序可使用参数标记   (?)   在相应位置代替   ntext、text   或   image   列中的值,以执行   INSERT   或   UPDATE   语句。参数标记(对   ADO   而言则为参数)被绑定到一个足以容纳数据块的程序变量上。应用程序进入循环,在循环中先将下一组数据移到绑定的变量中,然后调用   API   函数或方法写入数据块。这一过程将反复进行,直到整个数据值发送完毕。    
  使用   text   in   row  
  在   Microsoft   SQL   Server   2000   中,用户可以在表上启用   text   in   row   选项,以使该表能够在其数据行中存储   text、ntext   或   image   数据。  
   
  若要启用该选项,请执行   sp_tableoption   存储过程,将   text   in   row   指定为选项名并将   on   指定为选项值。BLOB(二进制大对象:text、ntext   或   image   数据)行中可以存储的默认最大大小为   256   字节,但是值的范围可以从   24   到   7000。若要指定默认值以外的最大大小,请指定该范围内的整数作为选项值。  
   
  如果应用下列条件,则将   text、ntext   或   image   字符串存储在数据行中:    
   
  启用   text   in   row。  
   
   
  字符串的长度比   @OptionValue   所指定的限制短  
   
   
  数据行中有足够的可用空间。    
  当   BLOB   字符串存储在数据行中时,读取和写入   text、ntext   或   image   字符串可以与读取或写入字符串和二进制字符串一样快。SQL   Server   不必访问单独的页以读取或写入   BLOB   字符串。    
   
  如果   text、ntext   或   image   字符串比行中所指定的限制或可用空间大,则将指针存储在该行中。在行中存储   BLOB   字符串的条件仍然适用,但是:数据行中必须有足够的空间容纳指针。    
   
  有关更多信息,请参见   sp_tableoption。  
   
  使用文本指针  
  如果未指定   text   in   row   选项,text、ntext   或   image   字符串将存储在数据行外;只有这些字符串的文本指针驻留在数据行中。文本指针指向由内部指针生成的树的根节点,而这些内部指针映射到实际存储(text、ntext   或   image   数据的)字符串段的页。    
   
  SQL   Server   2000   中的行文本指针与   SQL   Server   早期版本中的文本指针不同。行文本指针的行为就象   BLOB   数据的文件句柄;早期的文本指针功能则象   BLOB   数据的地址。因此,在使用行文本指针时,请记住下列特性:  
   
   
   
  重要     虽然游标中允许有行文本,但却不允许有行文本指针。如果尝试声明包含行文本指针的游标,SQL   Server   将返回错误信息(8654、16、1、"A   cursor   plan   could   not   be   generated   for   the   given   statement   because   it   contains   textptr(inrow   lob)."、1033)。  
   
  数字    
  对于每个数据库,每个事务最多允许   1024   个活动行文本指针。  
   
  锁定    
  当用户获取活动文本指针时,SQL   Server   2000   在第一个用户控制文本指针时锁定数据行,并确保没有其他用户修改或删除该行。锁在文本指针变为无效时被释放。若要使文本指针无效,请使用   sp_invalidate_textptr。  
   
  当事务的隔离级别是未提交读或者数据库为"只读"模式时,文本指针不能用于更新   BLOB   值。  
   
  当数据库为"单用户"模式时,SQL   Server   2000   不锁定数据行。  
   
  为举例说明,给出下面的表:  
   
  CREATE   TABLE   t1   (c1   int,   c2   text)  
  EXEC   sp_tableoption   't1',   'text   in   row',   'on'  
  INSERT   t1   VALUES   ('1',   'a')  
   
  下面的事务将会成功:  
   
  INSERT   t1   VALUES   ('1','This   is   text.')  
  SET   TRANSACTION   ISOLATION   LEVEL   READ   UNCOMMITTED  
  GO  
  BEGIN   TRAN  
  DECLARE   @ptr   varbinary(16)  
  SELECT   @ptr   =   textptr(c2)  
  FROM   t1  
  WHERE   c1   =   1  
  READTEXT   t1.c2   @ptr   0   5  
  COMMIT   TRAN  
  GO  
   
  下面的事务将会失败:  
   
  SET   TRANSACTION   ISOLATION   LEVEL   READ   UNCOMMITTED  
  GO  
  BEGIN   TRAN  
  DECLARE   @ptr   varbinary(16)  
  SELECT   @ptr   =   textptr(c2)  
  FROM   t1  
  WHERE   c1   =   1  
  WRITETEXT   t1.c2   @ptr   'xx'  
  COMMIT   TRAN  
  GO  
   
  持续时间    
  行文本指针仅在事务内有效。提交事务时,文本指针变为无效。  
   
  在某个事务内,当发生下列任一操作时,行文本指针可能无效:  
   
  会话结束。  
   
   
  删除该事务中的数据行。(其它事务无法删除数据行,因为该行包含锁。)  
   
   
  文本指针所在的表的架构已更改。使文本指针无效的架构更改操作包括:创建或除去聚集索引,改变或除去表,截断表,通过   sp_tableoption   更改   text   in   row   选项,以及执行   sp_indexoption。    
  使用前面的示例,下列脚本在   SQL   Server   早期版本中有效,但在   SQL   Server   2000   中将生成错误。  
   
  DECLARE   @ptrval   varbinary(16)  
  PRINT   'get   error   here'  
  SELECT   @ptrval   =   TEXTPTR(c2)  
  FROM   t1  
  WHERE   c1   =   1  
  READTEXT   t1.c2   @ptrval   0   1  
   
  在   SQL   Server   2000   中,必须在事务内使用行文本指针:  
   
  BEGIN   TRAN  
  DECLARE   @ptrval   varbinary(16)  
  SELECT   @ptrval   =   TEXTPTR(c2)  
  FROM   t1  
  WHERE   c1   =   1  
  READTEXT   t1.c2   @ptrval   0   1  
  COMMIT  
   
  NULL   文本    
  可以在由   INSERT   生成的   NULL   文本上获得行文本指针。而在以前,只有将   BLOB   更新为   NULL   后才能获得文本指针。  
   
  例如,下列代码在   SQL   Server   7.0   中无效,但在   SQL   Server   2000   中有效。  
   
  SET   TRANSACTION   ISOLATION   LEVEL   READ   COMMITTED  
  GO  
  INSERT   INTO   t1   VALUES   (4,   NULL)  
  BEGIN   TRAN  
  DECLARE   @ptrval   VARBINARY(16)  
  SELECT   @ptrval   =   TEXTPTR(c2)  
  FROM   t1  
  WHERE   c1   =   4  
  WRITETEXT   t1.c2   @ptrval   'x4'  
  COMMIT  
   
  在   SQL   Server   7.0   中,必须执行下列操作:  
   
  INSERT   INTO   t1   VALUES   (4,   NULL)  
  UPDATE   t1    
          SET   c2   =   NULL    
          WHERE   c1   =   4  
  DECLARE   @ptrval   VARBINARY(16)  
  SELECT   @ptrval   =   TEXTPTR(c2)  
  FROM   t1  
  WHERE   c1   =   4  
  WRITETEXT   t1.c2   @ptrval   'x4'  
   
  下表汇总差别。  
   
  差别   行文本指针   非行文本指针    
  数字   对于每个数据库,每个事务最多允许   1024   个活动行文本指针。   无限制。    
  锁定   将数据行一直   S   锁定到指针变为无效为止。    
  当事务为"未提交读"或数据库为"单用户"或"只读"模式时不获取锁。  
    不锁定数据行。    
  持续时间   事务或会话结束、删除行或更改表的架构时变为无效。   删除行时变为无效。    
  NULL   文本   插入   NULL   文本后可立即获取。   只有更新后才能获取。    
   
   
  通过数据库   API   使用   ntext、text   和   image   数据  
  这一部分概述数据库   API   处理   ntext、text   和   image   数据的方式:    
   
  ADO    
  ADO   可以将   ntext、text   或   image   列或参数映射为   Field   或   Parameter   对象。使用   GetChunk   方法逐块检索数据,使用   AppendChunk   方法逐块写数据。有关更多信息,请参见管理   Long   数据类型。    
   
  OLE   DB    
  OLE   DB   使用   ISequentialStream   接口支持   ntext、text   和   image   数据类型。ISequentialStream::Read   方法逐块读取长数据,ISequentialStream::Write   方法将长数据逐块写入数据库。有关更多信息,请参见   BLOB   和   OLE   对象。  
   
  ODBC    
  ODBC   具有一种称为"执行中的数据"的功能,可用于处理长数据的   ODBC   数据类型:SQL_WLONGVARCHAR   (ntext)、SQL_LONGVARCHAR   (text)   和   SQL_LONGVARBINARY   (image)。这些数据类型被绑定到某个程序变量上。这样一来,就可以调用   SQLGetData   逐块检索长数据,调用   SQLPutData   逐块发送长数据。有关更多信息,请参见管理   text   和   image   列。    
   
  DB-Library    
  DB-Library   应用程序也是将   ntext、text   和   image   列绑定到程序变量上。DB-Library   函数   dbtxtptr   用于获取指向数据库中长列出现位置的指针,dbreadtext   则用来逐块读取长数据。dbwritetext、dbupdatetext   和   dbmoretext   之类的函数用于逐块写入长数据。    
   
   
   
  说明     不支持使用   DB-Library   访问行文本。  
   
  有关更多信息,请参见   Text   和   Image   函数。    
   
  ©1988-2000   Microsoft   Corporation。保留所有权利。  
  Top

5 楼shadou(乷乧)回复于 2003-04-04 11:21:21 得分 0

studyTop

6 楼shadou(乷乧)回复于 2003-04-04 11:22:20 得分 0

UPTop

7 楼yhec(@_@ 俺是贫农俺怕谁)回复于 2003-04-04 11:22:59 得分 0

看不懂呀Top

8 楼hong_flood(洪)回复于 2003-04-04 11:44:03 得分 10

在Delphi中可用流来实现:  
   
  procedure   SetBlobMemo(Field:TField;RichEdit:TRichEdit);   //设置备注型字段  
  var  
    Ms:TMemoryStream;  
  begin  
    Ms:=TMemoryStream.Create;    
    try  
      RichEdit.Lines.SaveToStream(Ms);  
      Ms.Position:=0;  
      TBlobField(Field).LoadFromStream(Ms);  
    finally  
      Ms.Free;  
    end;  
  end;  
   
  procedure   ExecSQl;  
  begin  
      with   AQry_Common   do  
      begin  
          SQL.clear;  
          SQl.add('       :   Memo   ');  
          SetBlobMemo(Parameters.ParamByName('Memo'),   RichEdit1);  
          ExecSQl;  
      end;  
  end;  
  Top

相关问题

  • 怎样用SQL语句放图片进BLOB字段呢?
  • 如何写SQL语句插入一条带有BLOB字段的记录?
  • 一个SQL语句的字段问题
  • 请教设置字段的SQL语句
  • 更改字段顺序 SQL 语句
  • 如何追加字段,求sql语句?
  • 求sql语句A表1字段=B表1字段+B表2字段??
  • [求助]用SQL语句可以写入带Blob Field字段的数据库记录吗?
  • [求助]用SQL语句可以写入带Blob Field字段的数据库记录吗?
  • 如何将InterBase数据库的Blob字段转换为VarChar 字段,求教操作方法,最好是Sql语句!

关键词

  • sql server 2000
  • 指针
  • 数据
  • 文本
  • 语句
  • 数据库
  • 字段
  • 函数
  • 应用程序
  • 选项

得分解答快速导航

  • 帖主:yhec
  • xiaoxiao197821
  • BCB
  • BCB
  • BCB
  • hong_flood

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo