在线等待:请问如何用ADO读取SQL Server中的BLOB字段? 在线等待:请问如何用ADO读取SQL Server中的BLOB字段? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 转一篇BLOB在数据库的表中实际上是以二进制数据的形式存放的。由于BLOB的特殊性,一般的程序都无法处理它。比如,如果在一张表中存在BLOB,当用Dattabase Desktop(Delphi在带的数据库管理工具)打开它时,BLOB列将只显示BLOB字样。至于该列中实际存的是什么数据是单靠Database DeskTop是无法得到的。如果在我们编制的程序中,用DBGrid控件打开一个有BLOB字段的表,效果也一样。我们的程序无法直接显示、编辑以及插入BLOB字段。可见,常规的方法是不能满足要求的。 如何处理BLOB字段,可以借鉴一些可视的桌面数据库的方法。如Access中,BLOB字段是可以通过双击该字段的方式打开。Access是通过OLE的方式实现BLOB数据的编辑及处理的,所以我们也可以在通过程序中设置OLE控件的方法来处理BLOB。下面,我们先讨论操作BLOB的关键问题,然后给出一个简单的例子。操作BLOB的关键要在程序中自如地操作BLOB数据,无非是解决以下几个问题:1. BLOB数据的入库操作2. BLOB数据的显示3. BLOB数据的编辑、修改 由于数据的类型可能千变万化,所以,采用OLE方式是较方便的选择。我们可以在程序中放置一个OLE控件,用于显示、编辑各种BLOB数据。那么,问题的关键就是BLOB数据如何入库,以及数据库如何与OLE控件之间传递数据。第一种解决方案是在库中直接保存原始数据。具体方法如下: BLOB数据的入库:要把BLOB数据入库,不能向普通的数据那样直接赋值;而是利用BLOB字段的LoadFromfile方法。采用这个方法,可以直接将各种数据的数据文件存入数据库。代码如下:AblobField.LoadFromfile(aFileName); 数据库与OLE控件间的数据传递也要通过数据文件。即,BLOB字段先将数据存盘;然后,OLE从将数据文件中创建所需要的OLE对象。代码如下:AblobField.SaveToFile(aFileName);AOleContainer.CreateObjectFromFile(aFileName);注意:OLE对象不能直接使用LoadFromFile方法,因为,数据库中存放的BLOB对象的格式是文件原来的格式,而不? E格式,是不能直接读取的。直接读取将导致运行错误。 第二种方案是在库中以OLE格式保存数据。具体方法如下: 本方案的不同之处,在于数据入库前先进行格式的转换。格式的转换是通过OLE控件完成的。即,先创建OLE对象,然后入库。示例代码如下:AOleContainer.CreateObjectFromFile(aFileName);AoleContainer.SaveToFile(tmpFileName);AblobField.LoadFromfile(tmpFileName); 这样作的好处是,由于库中直接存储的是OLE格式,所以,在库与OLE控件之间的数据传递将非常方便。在这种情况下,可以通过文件直接传递:数据字段先将数据存到一个临时文件中,然后,OLE控件从临时文件中读取。即:AblobField.SaveToFile(aFileName);AOleContainer.LoadFromFile(aFileName);另外,还可以通过内存流来完成。使用内存流,可减少磁盘操作,大大提高运行效率。即:AblobField.SaveToStream(aStream);AOleContainer.LoadFromStream(aStream);下面是一个简单的例子。一个简单的例子 本例中,采用Paradox数据库。库中有两个字段,一个是字符型,另一个是BLOB型。我们在主Form上放一个OLE控件用于编辑及转换数据。一个ADOTable控件操作数据库。源代码如下:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, OleCtnrs, DB, ADODB, Grids, DBGrids;type TForm1 = class(TForm) ADOTable1: TADOTable; ADOTable1DocuID: TWideStringField; ADOTable1DocuContent: TBlobField; OleContainer1: TOleContainer; Button1: TButton; OpenDialog1: TOpenDialog; DBGrid1: TDBGrid; DataSource1: TDataSource; OpenTable: TButton; CloseTable: TButton; procedure Button1Click(Sender: TObject); procedure OpenTableClick(Sender: TObject); procedure ADOTable1AfterScroll(DataSet: TDataSet); procedure CloseTableClick(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);varfn: string;beginADOTable1.Edit; if OpenDialog1.Execute then begin //打开文件fn := ExtractFileName(OpenDialog1.FileName);ADOTable1DocuID.AsString := fn;OleContainer1.CreateObjectFromFile(OpenDialog1.FileName, False); //创建OLE对象OleContainer1.SaveToFile('tmp'); //将OLE数据存入临时文件ADOTable1DocuContent.LoadFromFile('tmp'); //将OLE数据存入数据库ADOTable1.UpdateRecord;end;end;procedure TForm1.OpenTableClick(Sender: TObject);begin ADOTable1.Open ;end;procedure TForm1.ADOTable1AfterScroll(DataSet: TDataSet);beginif not ADOTable1DocuContent.IsNull then beginADOTable1DocuContent.SaveToFile('tmp'); //数据存入临时文件OleContainer1.LoadFromFile('tmp'); //从临时文件中读取OLE对象end;end;procedure TForm1.CloseTableClick(Sender: TObject);begin ADOTable1.Close ;end;procedure TForm1.FormCreate(Sender: TObject);beginend;end. var SFileName: string; BS: TAdoBlobStream;begin BS := TAdoBlobStream.Create(TBlobField(ADODataSet1.FieldByName('FileMatter')), bmRead); try SFileName := Extractfilepath(application.ExeName) + 'tempfile.' + ADODataSet1.fieldbyname('FileExtra').AsString; BS.SaveToFile(SFileName); OleContainer1.CreateObjectFromFile(SFileName, false); finally BS.free; end;end; firetoucher的TAdoBlobStream.Create(TBlobField(ADODataSet1.FieldByName('FileMatter')), bmRead);导致死机了! TBlobFiled控件在哪里??? 内存流的使用问题 对线程一翘不通,就这么几行代码,CPU居然达到100% 金蝶数据库命名规范是什么 怎么样获取ie地址栏的url啊(急) 关于delphi7中窗体继承的问题 TDBComboBox控件 请教一个这个功能用什么控件可以实现的!多谢了 谁还遇到过这个问题:函数放在dll中就运行出错?? 用DELPHI編寫一個程序,當用記隻要移動了一下鼠標或敲了一下鍵盤時,就觸發一個事件。 急!!!能否在程序里实现把DBGrid的内容保存为EXCEL格式吗,50分送上? xpmenu在编辑情况下正常,执行之后什么效果也没有,请指点! 我做了一个非规则的无标题窗体,但不知怎么显示出菜单,不要弹出菜单
BLOB在数据库的表中实际上是以二进制数据的形式存放的。由于BLOB的特殊性,一般的程序都无法处理它。比如,如果在一张表中存在BLOB,当用Dattabase Desktop(Delphi在带的数据库管理工具)打开它时,BLOB列将只显示BLOB字样。至于该列中实际存的是什么数据是单靠Database DeskTop是无法得到的。如果在我们编制的程序中,用DBGrid控件打开一个有BLOB字段的表,效果也一样。我们的程序无法直接显示、编辑以及插入BLOB字段。可见,常规的方法是不能满足要求的。
如何处理BLOB字段,可以借鉴一些可视的桌面数据库的方法。如Access中,BLOB字段是可以通过双击该字段的方式打开。Access是通过OLE的方式实现BLOB数据的编辑及处理的,所以我们也可以在通过程序中设置OLE控件的方法来处理BLOB。下面,我们先讨论操作BLOB的关键问题,然后给出一个简单的例子。操作BLOB的关键
要在程序中自如地操作BLOB数据,无非是解决以下几个问题:
1. BLOB数据的入库操作
2. BLOB数据的显示
3. BLOB数据的编辑、修改
由于数据的类型可能千变万化,所以,采用OLE方式是较方便的选择。我们可以在程序中放置一个OLE控件,用于显示、编辑各种BLOB数据。那么,问题的关键就是BLOB数据如何入库,以及数据库如何与OLE控件之间传递数据。
第一种解决方案是在库中直接保存原始数据。具体方法如下:
BLOB数据的入库:要把BLOB数据入库,不能向普通的数据那样直接赋值;而是利用BLOB字段的LoadFromfile方法。采用这个方法,可以直接将各种数据的数据文件存入数据库。代码如下:
AblobField.LoadFromfile(aFileName);
数据库与OLE控件间的数据传递也要通过数据文件。即,BLOB字段先将数据存盘;然后,OLE从将数据文件中创建所需要的OLE对象。代码如下:
AblobField.SaveToFile(aFileName);
AOleContainer.CreateObjectFromFile(aFileName);
注意:OLE对象不能直接使用LoadFromFile方法,因为,数据库中存放的BLOB对象的格式是文件原来的格式,而不? E格式,是不能直接读取的。直接读取将导致运行错误。 第二种方案是在库中以OLE格式保存数据。具体方法如下:
本方案的不同之处,在于数据入库前先进行格式的转换。格式的转换是通过OLE控件完成的。即,先创建OLE对象,然后入库。示例代码如下:
AOleContainer.CreateObjectFromFile(aFileName);
AoleContainer.SaveToFile(tmpFileName);
AblobField.LoadFromfile(tmpFileName);
这样作的好处是,由于库中直接存储的是OLE格式,所以,在库与OLE控件之间的数据传递将非常方便。在这种情况下,可以通过文件直接传递:数据字段先将数据存到一个临时文件中,然后,OLE控件从临时文件中读取。即:
AblobField.SaveToFile(aFileName);
AOleContainer.LoadFromFile(aFileName);
另外,还可以通过内存流来完成。使用内存流,可减少磁盘操作,大大提高运行效率。即:
AblobField.SaveToStream(aStream);
AOleContainer.LoadFromStream(aStream);下面是一个简单的例子。一个简单的例子
本例中,采用Paradox数据库。库中有两个字段,一个是字符型,另一个是BLOB型。我们在主Form上放一个OLE控件用于编辑及转换数据。一个ADOTable控件操作数据库。源代码如下:unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtnrs, DB, ADODB, Grids, DBGrids;type
TForm1 = class(TForm)
ADOTable1: TADOTable;
ADOTable1DocuID: TWideStringField;
ADOTable1DocuContent: TBlobField;
OleContainer1: TOleContainer;
Button1: TButton;
OpenDialog1: TOpenDialog;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
OpenTable: TButton;
CloseTable: TButton;
procedure Button1Click(Sender: TObject);
procedure OpenTableClick(Sender: TObject);
procedure ADOTable1AfterScroll(DataSet: TDataSet);
procedure CloseTableClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
fn: string;
begin
ADOTable1.Edit;
if OpenDialog1.Execute then begin //打开文件
fn := ExtractFileName(OpenDialog1.FileName);
ADOTable1DocuID.AsString := fn;
OleContainer1.CreateObjectFromFile(OpenDialog1.FileName, False); //创建OLE对象
OleContainer1.SaveToFile('tmp'); //将OLE数据存入临时文件
ADOTable1DocuContent.LoadFromFile('tmp'); //将OLE数据存入数据库
ADOTable1.UpdateRecord;
end;
end;procedure TForm1.OpenTableClick(Sender: TObject);
begin
ADOTable1.Open ;
end;procedure TForm1.ADOTable1AfterScroll(DataSet: TDataSet);
begin
if not ADOTable1DocuContent.IsNull then begin
ADOTable1DocuContent.SaveToFile('tmp'); //数据存入临时文件
OleContainer1.LoadFromFile('tmp'); //从临时文件中读取OLE对象
end;
end;procedure TForm1.CloseTableClick(Sender: TObject);
begin
ADOTable1.Close ;
end;procedure TForm1.FormCreate(Sender: TObject);
beginend;end.
BS: TAdoBlobStream;
begin
BS := TAdoBlobStream.Create(TBlobField(ADODataSet1.FieldByName('FileMatter')), bmRead);
try
SFileName := Extractfilepath(application.ExeName) + 'tempfile.' + ADODataSet1.fieldbyname('FileExtra').AsString;
BS.SaveToFile(SFileName);
OleContainer1.CreateObjectFromFile(SFileName, false);
finally
BS.free;
end;
end;
TBlobFiled控件在哪里???