发现ADOQuery的SQL语句关于参数一个蛋疼的问题,寻找解决?

scoredhigh 2013-05-31 06:48:23
以下代码
ADOQuery_Exec->SQL->Clear();
ADOQuery_Exec->SQL->Text = "insert into tbl_ecg_review values('000', '111', '2013-09-05 12:34:23', :blob01, :blob02, :blob03, :blob04, :blob05, 'aaaaaa')";
ADOQuery_Exec->Parameters->Clear();
就是这三句代码,放在Timer1的OnTimer里,设置定时器时间间隔为20毫秒,然后打开任务管理器,查看内存使用状况,会发现内存不断增加。
如果我将SQL语句中的参数去掉,就不会有内存泄露的问题。
看起来ADOQuery控件的sql语句只要碰见“:”,就会自动创建一个TParameter对象,然而“ADOQuery_Exec->Parameters->Clear();”一点不起作用,竟然是这个原因造成内存泄露,真是蛋疼。
这个要怎么解决?
就是说不需要参数也可以向数据库插入Blob类型的数据?或者参数是静态的,设计时手工添加,不在SQL语句中用“:”表现出来,要怎么弄?

...全文
291 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
引用 19 楼 ksrsoft 的回复:
blob只能通过参数了, 你把adoqery动态创建,执行完一个sql后delete query, 然后执行时再动态创建,这样试试
刚才试过了,还是有内存泄露。
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
引用 19 楼 ksrsoft 的回复:
blob只能通过参数了, 你把adoqery动态创建,执行完一个sql后delete query, 然后执行时再动态创建,这样试试
哦,我试试看,我用的是CB6,有没有可能是这个版本的一个bug
缘中人 2013-06-03
  • 打赏
  • 举报
回复
blob只能通过参数了, 你把adoqery动态创建,执行完一个sql后delete query, 然后执行时再动态创建,这样试试
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
经过测试,如果我将SQL语句改为 ADOQuery_Exec->SQL->Text = "insert into tbl_ecg_review values(:coder, :medno, :time, 'blob01', 'blob02', 'blob03', 'blob04', 'blob05', 'aaaaaa')"; 同样会有内存泄露的问题。 如果改为: ADOQuery_Exec->SQL->Text = "insert into tbl_ecg_review values ('000', '111', '2013-09-05 12:34:23', 'blob01', 'blob02', 'blob03', 'blob04', 'blob05', 'aaaaaa')"; 就不会有内存泄露的问题,即使执行ADOQuery_Exec->ExecSQL();真正插入数据,也不会有内存的问题。 这就表示纯是参数的原因,想知道目前Blob类型不用参数还有没有方法可以向数据库插入数据的? PS:用ADOStoredProc同样有内存泄露的问题,大概原因一样。 这真是蛋疼啊,怎么解决,怎么解决,怎么解决,急人啊?
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
让这个帖子多呆一会儿
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
引用 23 楼 PPower 的回复:
SQL 2005以后的一个方法: INSERT INTO MyTable(ID, BLOBField) SELECT 1001,* FROM OPENROWSET(BULK N'C:\a.jpg', SINGLE_BLOB) as photo INSERT INTO MyTable(ID, BLOBField) Values(1001,0xCB09ABCDABCDABCD08650066) 你试试看行不行吧。 或者升级到 XE4 , 也挺好的。我现在只装了XE4
多谢大虾啊,你真厉害,原来不用参数也可以存储blob字段,你这个方法是可行的啊,呵呵
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
引用 23 楼 PPower 的回复:
SQL 2005以后的一个方法: INSERT INTO MyTable(ID, BLOBField) SELECT 1001,* FROM OPENROWSET(BULK N'C:\a.jpg', SINGLE_BLOB) as photo INSERT INTO MyTable(ID, BLOBField) Values(1001,0xCB09ABCDABCDABCD08650066) 你试试看行不行吧。 或者升级到 XE4 , 也挺好的。我现在只装了XE4
嗯,只能这样一试了 INSERT INTO MyTable(ID, BLOBField) Values(1001,0xCB09ABCDABCDABCD08650066) 这种方法可以吗,假如我200个字节的数据,可以0xAC0A5....34(一共200字节),如果能够这样,倒是不失为一个解决的方法
勉励前行 2013-06-03
  • 打赏
  • 举报
回复
SQL 2005以后的一个方法: INSERT INTO MyTable(ID, BLOBField) SELECT 1001,* FROM OPENROWSET(BULK N'C:\a.jpg', SINGLE_BLOB) as photo INSERT INTO MyTable(ID, BLOBField) Values(1001,0xCB09ABCDABCDABCD08650066) 你试试看行不行吧。 或者升级到 XE4 , 也挺好的。我现在只装了XE4
scoredhigh 2013-06-03
  • 打赏
  • 举报
回复
下了个c++ builder2010跑了下,同样的问题: ADOQuery_Exec->SQL->Clear(); ADOQuery_Exec->SQL->Text = "insert into tbl_ecg_review values('000', '111', '2013-09-05 12:34:23', :blob01, :blob02, :blob03, :blob04, :blob05, 'aaaaaa')"; ADOQuery_Exec->Parameters->Clear(); 三句代码放到定时器事件里,间隔时间设置为20毫秒,打开任务管理器,会观察到内存渐渐增长
scoredhigh 2013-06-01
  • 打赏
  • 举报
回复
引用 16 楼 cankoo 的回复:
我都是用ADO的,没有过这种问题。ADO是微软的技术呢。
ADO底层确实是微软的技术,但是BCB里的ADO组件除了封装的底层,一定也加了自己的类处理的。 因为目前的程序是每秒接受数据然后存入mysql数据库,一般是很难发现,但是我们的程序跑了一个星期后,就发现内存被占满,系统崩溃 主要是因为有blob字段,必须用到参数存储,我现在准备用 ADO的存储过程组建试试看,看行不行
cankoo 2013-06-01
  • 打赏
  • 举报
回复
我都是用ADO的,没有过这种问题。ADO是微软的技术呢。
scoredhigh 2013-06-01
  • 打赏
  • 举报
回复
引用 14 楼 sczyq 的回复:
'2013-09-05 12:34:23' 这个也变成参数
实际上这时候的SQL语句因为根本没有执行,并不一定是个标准的SQL语句,可以是任意的一段字符串, 我之所以觉得蛋疼,就是发现ADOQuery控件在SQL->Text被字符串赋值以后,会自动搜索字符串,发现带“:”后面跟一串字符的就认为是参数,然后自动生成参数对象,相当于自动执行了ADOQuery_Exec->Parameters->CreateParameter函数,我估计这就是内存泄漏的缘由,但是为什么用ADOQuery_Exec->Parameters->Clear()或者是对每个自动生成的参数使用Free()还是会内存泄漏让我困扰
sczyq 2013-06-01
  • 打赏
  • 举报
回复
'2013-09-05 12:34:23' 这个也变成参数
scoredhigh 2013-05-31
  • 打赏
  • 举报
回复
引用 12 楼 PPower 的回复:
我用WIN7+XE4试,没问题,用资源监视器查看内存非常稳定。现在CB版本众多,如果低版本的不行,就升级好了。
我用的是xp+CB6,以前一直是做嵌入式的,现在要在pc上做应用,就开始学c++ builder,目前边学边做项目搞了两个月,刚开始觉得好方便,好好用啊,现在做起来才发现问题多多啊
勉励前行 2013-05-31
  • 打赏
  • 举报
回复
我用WIN7+XE4试,没问题,用资源监视器查看内存非常稳定。现在CB版本众多,如果低版本的不行,就升级好了。
scoredhigh 2013-05-31
  • 打赏
  • 举报
回复
引用 9 楼 ccrun 的回复:
个人猜测,通过SQL语句中代入参数,在ExceSQL以后,数据集组件会负责释放这些相应的资源。 需要花点时间研究源码。
哦,因为最开始ExceSQL以后,发现有内存泄漏,就一步一步测试,发现竟然是这个参数的原因。 最开始怀疑,以为是mysql执行了插入语句后再在缓冲的数据一直未释放导致的内存泄漏,后来测试发现如果不用参数的形式插入数据,就不会有内存泄漏的现象。 一步一步注释代码后发现,最后只剩那三句代码也会有内存泄漏的情况。
scoredhigh 2013-05-31
  • 打赏
  • 举报
回复
引用 7 楼 ksrsoft 的回复:
用Parameters方式给数据库插入int和string类型,看是否内存不断增长
我认为内存应该会,因为ADOQuery控件只要检测到SQL->Text里有":"符号,就会自动创建参数,这时候参数的类型并不是ftBlob。 ADOQuery_Exec->SQL->Clear(); ADOQuery_Exec->SQL->Text = "insert into tbl_ecg_review values('000', '111', '2013-09-05 12:34:23', :blob01, :blob02, :blob03, :blob04, :blob05, 'aaaaaa')"; 这两句执行后,ADOQuery_Exec->Parameters->Count就自动变成5,已经自动生成的参数,这时候还未指定参数blob01,blob02,blob03,blob04,blob05的类型
ccrun.com 2013-05-31
  • 打赏
  • 举报
回复
个人猜测,通过SQL语句中代入参数,在ExceSQL以后,数据集组件会负责释放这些相应的资源。 需要花点时间研究源码。
scoredhigh 2013-05-31
  • 打赏
  • 举报
回复
引用 6 楼 ccrun 的回复:
你为什么要Parameters->Clear()呢?
用这个主要是想测试Parameters->Clear()是不是将自动创建的TParameter给释放掉,虽然显示TParameter->Count为零,但是测试的结果是内存没有释放啊。
缘中人 2013-05-31
  • 打赏
  • 举报
回复
用Parameters方式给数据库插入int和string类型,看是否内存不断增长
加载更多回复(6)

1,178

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 数据库及相关技术
社区管理员
  • 数据库及相关技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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