急!关于mysql的blob字段!高分相送。

alittlefrag 2002-03-23 01:24:41
我在DELPHI5中用ODBC连接MYSQL数据库
发现BLOB字段最多只能写几百K,再大就不行了
请问要设置哪儿才行啊!
急需!
...全文
753 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
alittlefrag 2002-04-02
  • 打赏
  • 举报
回复
用mysql的连接库libmysql访问mysql数据库
mysql连接库是访问mysql数据库的最直接,最快速的方式,只要作以下服务器设置,随便存多大的文件都没关系
max_allowed_packet需要在winmysqladmin中的my.ini Setup选项中配置,以使每次mysqld-nt.exe启动时都有效,在
[WinMySQLadmin]
Server=D:/Program Files/mysql/bin/mysqld-nt.exe
之前添加语句set-variable =max_allowed_packet=16m,’16m’表示mysql客户端和服务器端通信缓冲区的大小,默认客户端24m,服务器端1m,所以要想执行超过1m的客户与服务器的sql查询,必须设置自己需要的大小,注意,在执行命令行启动的时候也可以如下运行"D:\Program Files\mysql\bin\mysqld-nt.exe" --set-variable=max_allowed_packet=16m 但只对本次运行有效.

以下对一些常用函数的用法按调用顺序作了一个简单的说明。
1.连接mysql数据库
连接用到两个函数:mysql_init()和mysql_real_connect(),定义如下:
MYSQL *mysql_init(MYSQL *mysql);
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag);
mysql_init初始化mysql句柄,供mysql_real_connect使用,如果mysql是一个NULL指针,函数分配、初始化并且返回一个新对象。否则对象被初始化并且返回对象的地址。mysql_real_connect 根据提供的mysql数据库服务器的地址,mysql用户名,密码,数据库名称,端口,等建立同数据库的连接,unix_socket一般为NULL,client_flag一般为0,如有特殊要求参见mysql参考手册。如果连接成功,一个 MYSQL*连接句柄。如果连接失败,NULL。
2.查询
查询有两个函数mysql_query()和mysql_real_connect()
int mysql_query(MYSQL *mysql, const char *query);
int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length);
mysql为mysql_real_connect返回的句柄,query为sql语句,mysql_query的query中不能包含含有’\0’的二进制数据,而mysql_real_query可以,然而,在插入blob字段时,你可以用mysql_escape_string先进行转换。若查询成功,两个函数都返回零。
3.存储结果
连接库定义了一个结果集的结构:MYSQL_RES,来存储返回的结果;根据不同的查询,返回的结果不同,以下是几种常见的结果;
数据记录:Select语句返回的满足条件的记录;
表结构:mysql_list_fields或SHOW COLUMNS FROM tbl_name [LIKE wild]语句返回
数据表:mysql_list_tables或SHOW tables [LIKE wild]返回
数据库:mysql_list_dbs或SHOW databases [LIKE wild]返回
用mysql_query或mysql_real_query查询时,要用mysql_store_result()或mysql_use_result()保存结果,他们都返回一个MYSQL_RES结构指针。mysql_list_fields,mysql_list_tables,mysql_list_dbs,直接返回MYSQL_RES结构指针,存储查询结果之后,就可以调用函数来取出需要的数据。4. 取数据
以下是一些常用的取数据的函数:
a. MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);获取结果集中的一个字段信息,可连续调用直到返回NULL。
b. unsigned int mysql_num_fields(MYSQL *mysql);返回结果集中的字段数。
c. MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);获取结果集中的一行记录,可连续调用直到返回NULL。返回值是一个字符串数组的指针。
d. unsigned long *mysql_fetch_lengths(MYSQL_RES *result);返回结果集中当前行的每个字段的长度,返回值是一个整数数组的指针。必须在mysql_fetch_row之后调用,以和mysql_fetch_row检索的记录对应。可连续调用直到返回NULL。
以上只是对一些常用的连接库函数按调用顺序作了一个简单的说明,详细资料参见mysql的使用手册。
直接用mysql连接库在构建用户界面方面有一些麻烦,Delphi的TClientDataSet 组件可以创建内存表,在不需要很全面的功能的时候,用它来作为用户和mysql数据库之间的桥梁,非常方便。
以下是一个创建表的函数,类型转换不全,只转换了几种我需要的。
function CreateResultTable(szsql:string;pmysqlstruct:PMYSQL;
var cds:TClientDataSet):integer;
type
arrinteger=array[00..$ff] of integer;
PArrinteger=^arrinteger;
var
row :PMYSQL_ROW;
num_fields:integer;
i:integer;
presult:PMYSQL_RES;
pmyfield:PMYSQL_FIELD;
plengths:PArrinteger;
strm:TMemoryStream;
begin
result:=0;
if mysql_query(pmysqlstruct,PChar(szsql))<>0 then begin
Result :=1;
Exit;
end;
presult:=mysql_store_result(pmysqlstruct);
if presult=nil then begin
Result:=2;
Exit;
end;
cds.Close;
cds.FieldDefs.Clear;
pmyfield:=mysql_fetch_field(presult);
while pmyfield<>nil do begin
with cds.FieldDefs.AddFieldDef do begin
Name:=pmyfield.name;
case pmyfield._type of
FIELD_TYPE_LONG,FIELD_TYPE_LONGLONG: DataType:=ftLargeint;
FIELD_TYPE_DATETIME: DataType:=ftDateTime;
FIELD_TYPE_VAR_STRING,FIELD_TYPE_STRING:
begin
DataType:=ftString;
size:=pmyfield.length;
end;
FIELD_TYPE_BLOB,FIELD_TYPE_TINY_BLOB,FIELD_TYPE_MEDIUM_BLOB,FIELD_TYPE_LONG_BLOB: DataType:=ftBlob;
else DataType:=ftUnknown;
end;
end;
pmyfield:=mysql_fetch_field(presult);
end;
try
cds.CreateDataSet;
except
mysql_free_result(presult);
Result:=3;
Exit;
end;
strm:=TMemoryStream.Create;
{strList是字段的显示对照字典,根据需要创建一个TStringList,作如下初始化:strList.Text:='UserID=序列号'+#13+'UserName=用户名'+#13 ...;}
{ for i:=0 to cds.FieldCount-1 do
begin
if strList.Values[cds.FieldDefs[i].name]<>'' then
cds.Fields[i].DisplayLabel:=strList.Values[cds.FieldDefs[i].name];
end;}
num_fields:= mysql_num_fields(presult);
row:=mysql_fetch_row(presult);
if row=nil then result:=4;
while (row<>nil) do
begin
plengths:=PArrinteger(mysql_fetch_lengths(presult));
cds.Insert;

for i:=0 to num_fields-1 do
begin
with cds.Fields[i] do begin
if IsBlob then begin
strm.Clear;
strm.Write(row[i]^,plengths[i]);
(cds.Fields[i] as TBlobField).LoadFromStream(strm);
end
else cds.Fields[i].AsString:=row[i];
end;
end;
cds.Post;
row:=mysql_fetch_row(presult);
end;
strm.Free;
mysql_free_result(presult);
end;

alittlefrag 2002-03-27
  • 打赏
  • 举报
回复
百般无奈之下,直接用api了,
谢谢各位提供的思路,给分!
alittlefrag 2002-03-23
  • 打赏
  • 举报
回复
还是不行啊
我把MAXBUFSIZE改为10240
BLOB SIZE 改为5120
但最大也不能超过1M
bigysw 2002-03-23
  • 打赏
  • 举报
回复
很老的老问题了,如果BDE,就是像 抽烟的鱼 那样整。
别的用 ADO 吧!
forgot 2002-03-23
  • 打赏
  • 举报
回复
TBlobField(Table.FieldByName('xxx')).LoadFromFile 看来有限制,

而同是bde,用query的 insert into ... values(... , :blob_field)
query.ParamByName('blob_field').LoadFromFile('...',ftBlob)
query.ExecSQL
保存oracle的long raw类型,保存30m的文件都没事

(只是读出比较麻烦,我只好用ado来读出。ado确实没有限制,而bde很小就不行了)
CeleronII 2002-03-23
  • 打赏
  • 举报
回复
哦,这个问题我遇到过。
你首先进入BDE的Configuration页里面,
进入System->INIT的属性页里面,有个MAXBUFSIZE属性,把它改大点,我也应该可以了,还有本身的BLOB SIZE也要改大点
我以前在DB2里面试过,可以的,我想SQL也不例外吧

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧