RecordCount,RecNo及数据库图形字段(Image)几个问题的讨论。---TR@SOE(),ALNG(阿良)及各位高手都来呀!! 

luhongjun 2001-04-14 11:47:00
加精
在这几个问题上已经有不少帖子讨论过:
综合一下:
对于RecordCount,RecNo问题

问题:

使用MSSQL7,在用Query对数据集进行查询后,想用recordcount得到查询出的纪录个数,可是结果竟是-1!!!在DBGrid中明明显示有两条纪录,我百思不得其解,请问是什么原因?还有什么办法求数据集纪录个数?

RecNo无法返回正确的结果

TR@SOE()兄的说法是:

对于C/S数据库,如果以TABLE为基础的数据集而言,那么我认为RecordCount/RecNo都是不可靠的,除非你确信在任何时候都只有一个用户、一个连接;这里当然还牵涉到C/S数据库对数据库修改的读写状态,例如一个数据库的TransIsolation可以设置为tiReadCommitted/tiDirtyRead/tiRepeatableRead,这也会影响每次刷新TABLE时对别的用户做的修改的处理。具体可以看帮助。在BCB的帮助中,对于这三个取值有详细的描述,并且给出了不同的数据库所支持的最低级别。对于Sybase, MS-SQL,最低的也要求tiReadCommitted,且不支持tiRepeatableRead。所以,Count/No都是不可靠的了。

在当地数据库的情况下,由于这种数据库的锁定是针对数据库的,而不是针对记录的,使用Count/No是可以的,但是本身这个机制带来的问题是显而易见的,不在这里讨论了。

以前我看到BCB还是WINGSUN曾经建议过用ADO,据说在ADO中COUNT/NO都是正确的,不妨试一下。
解决的方法:
select count(*) as totalcount from ..... where (和你原来的那个QUERY一样的条件)
然后在程序中读totalcount即可。。。。。


ALNG(阿良)兄的说法:
用ADO.(我不知道ADO的RecordCount和RecNo是否一定正确)
解决的方法:
RecDM->RecQr->Close();
RecDM->RecQr->SQL->Clear();
RecDM->RecQr->SQL->Add(QueryStr);//QueryStr为一Select语句
RecDM->RecQr->Open();
//-----
RecDM->RecQr->Last();
RecDM->RecQr->First();
//--------------------
I=RecDM->RecQr->RecordCount;

对于数据库(以MSSQL7.0为例)使用Image字段存储图形的问题:

问题:显示数据库中的图形字段出现“无效的数据格式 ”的提示

我的观点:
关于JPEG文件在数据库中的存储问题
个人认为:数据库中只能存储BitMaps格式的文件。如果使用TblobField的LoadFromFile把JPG
图象导入Image字段显示时报错:无效的数据格式 。
为什么但使用剪贴板就不出现任何问题?
实际上使用剪贴板在存储时也把jpeg格式自动转化成BITMAPS格式。不信你可从图片的容量上计算一下。
因此:在MSSQL7.0的IMAGE字段中只能存储BITMAPS格式的图片。





...全文
291 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
TR@SOE 2001-04-18
  • 打赏
  • 举报
回复
Alng,

我一般不那样遍历数据库。

Qry->Open();
Qry->First();
while(!Qry->Eof)
{
//do something here.
Qry->Next();
}

你的代码中也要用到Qry->First(),否则你无法知道定位在哪里,如WINGSUN所云。
TR@SOE 2001-04-17
  • 打赏
  • 举报
回复
alng提到:
不过一行一行计算RecordCount不如select count(*) ...来的舒畅。不过后者不能保证一定准确。在多用户环境下,运行完前一个查询取得满足条件的记录数后再用另一个查询取得记录集时,可能已有了新的增删,造成不一致。

这种情况当然是存在的。但是,使用Last()/First()然后再获得RecordCount的方法至少有两个缺陷:一是在返回的数据集很大时,Last/First是很费时的;另外,如果不是QUERY返回的话,也存在别的用户已经修改了数据库的情况。

所以我觉得还是要用SELECT COUNT的方法。

ADO的RECORDCOUNT和RECNO我没有尝试过,不敢妄断。


dufeng3104 2001-04-17
  • 打赏
  • 举报
回复
关注
孩皮妞野 2001-04-17
  • 打赏
  • 举报
回复
>>TR@SOE

我的意思试要避免:
Qryy->Text="Select count(*) form...";
Qry->Open();

int RecCount=Qry->Fields->Fields[0]->AsInteger;

Qry->Close();
Qry->Text="Select * from ...";
Qry->Open();
for(int i=0;i<RecCount; i++){
//do some thing
Qry->Next();
}
可能出错,因为后者的RecCount已经不等于你前面保存的那个数了。

Wingsun的方法可以保证这方面的一致性,至于永远的一致性是不存在的,也是不必要的。
当然,这个办法代价高昂,让我选,我回选你的办法(如果Qry->RecCount不可靠的话),
只不过不要太依赖这个数,而是,

while(!Qry->Eof){
//Do some thing
Qry->Next();
}




TR@SOE 2001-04-17
  • 打赏
  • 举报
回复
解决了????怎么得分都是零的干活?
Hank 2001-04-17
  • 打赏
  • 举报
回复
根据实际情况说一下:

1、你返回RecNo干什么?用BookMark或索引不行吗?多花点时间做点有意义的事好不好?

2、返回RecordCount的问题只是目前的BDE版本有问题,用ADO不会,MS已经声明SQL-SERVER7.0及以上不支持DB-Library,BDE及低版本的ODBC本质上是通过DB-Library来访问SQL-Server的,所以通过BDE来访问SQL-SERVER7.0及以上会有很多问题!连接MS的东西最好用MS推荐的方法(ADO),否则会很惨,相信我们都没有能力提出一种另外的标准!

3、关于JPEG、GIF等格式的图片显示的问题,很多地方都有解释--用流来存储,显示也要用流来读取显示,任何格式都可以!用DELPHI或SQL-SERVER是不能直接读取或浏览的(此时是流),具体的例子在CSDN很多!
weenyboy 2001-04-17
  • 打赏
  • 举报
回复
recno只是本地数据库的概念,网络数据库已经没有记录号,所以始终返回-1
recordcount能够返回记录数量,当然多用户环境中仅仅返回你存取时候的记录数,也许它
不正确,那只是bug,不过,应该尽量避免使用,因为可能的导致性能等方面的原因
除非你需要特殊的记录数量统计,否则不必关心多用户造成的 影响
luhongjun 2001-04-16
  • 打赏
  • 举报
回复
TR@SOE()兄怎么没来
luhongjun 2001-04-16
  • 打赏
  • 举报
回复
TR@SOE()兄怎么没来
rh 2001-04-15
  • 打赏
  • 举报
回复
我来旁听……
luhongjun 2001-04-15
  • 打赏
  • 举报
回复
TR@SOE()兄怎么没来。
BCB 2001-04-14
  • 打赏
  • 举报
回复
向Blob中送JPEG,不能用LoadFromFile,可用文件流的办法送入BLOB流中,
BLOB可以接受任意格式的文件,包括JPG,
但TDBImage只能显示.BMP,对于.jpg就只能用间接的办法了

孩皮妞野 2001-04-14
  • 打赏
  • 举报
回复
同意斑竹。

不过一行一行计算RecordCount不如select count(*) ...来的舒畅。不过后者不能保证一定准确。在多用户环境下,运行完前一个查询取得满足条件的记录数后再用另一个查询取得记录集时,可能已有了新的增删,造成不一致。春阳兄的方法可以避免这一问题。

任何类型的数据都可存在BLOB里,数据库只管帮你存放,解释权在你。
「已注销」 2001-04-14
  • 打赏
  • 举报
回复
BDE有时候很幽默

就是需要Last一番才给你干活……
Wingsun 2001-04-14
  • 打赏
  • 举报
回复
根据我的经验,不管使用的是ADO还是BDE,如果要获取Query的记录数,不管是在何种开发语言工具,不管是VB、VC、Delphi、BCB等。最好的办法就是先将Query的结果集MoveLast(VB)、Last(BCB、Delphi)才能获得正确的RecordCount。好像是因为当通过Query来获得结果集的时候,当前的记录集指针指向了结果集中的一个不确定位置,然后实际的RecordCount的数值和当前的记录集指针曾经指向的位置有很大的关系,所以如果要获得确确的RecordCount数值,一定要先将记录集指针移到记录集末尾才能保证正确。如果用ADO的话,如果打开的数据集的方式不一样的话,由于返回的结果类型不一样(有只向前的、有有游标的、有可前后移动的等等),所以会导致返回的RecordCount不能代表实际的RecordCount。在这一些情况下,就需要通过如下的这一种方式来获得实际的RecordCount:
int i=0;
if(!Query1->Bof)//对于可随意移动游标的记录集,如果是只向前的记录集,这不需要这一步
Queyr1->First()
while(!Query1->Eof)
{
i++;
Query1->Next();
}
第二个问题:
我个人的经验表示,MSSQL的Image字段是可以存储任意类型的数据的,关键的问题是你的处理方法。
我是这样处理的:
TMemoryStream * pMem=new TMemoryStream();
pMem->LoadFromFile(FileName);
然后将这个pMem转存到TBlobStream中,然后在存取。
取出的过程刚好相反。
一般我不用TBlobStream的LoadFromFile,这个方法有很多的问题。
luhongjun 2001-04-14
  • 打赏
  • 举报
回复
BCB(:))
可否把存入及显示的办法向大家公布?使用剪贴板存入数据库中的图片是否已经转化成Bitmaps格式。

yukuang 2001-04-14
  • 打赏
  • 举报
回复
RecordCount =-1的问题我也碰到过。查过书和以前的贴子,得出了结论:BUG。

最可靠的方法还是select count(*)。但是这种不太方便。

请问各位高手还有无其它的方法?

1,178

社区成员

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

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