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

头疼……,TOP和ORDER BY的问题

楼主toumao(偷猫)2006-07-03 01:36:08 在 MS-SQL Server / 基础类 提问

头疼……  
   
  我编写的是短信处理程序,  
  就是有用户发短信参与我们的节目,  
  他可能发字母、数字等,可能发到不同的号码,  
  我这里根据他发送的内容,以及他发送到的目标号码来判断他参与的活动,  
  然后给他发送回应,  
  比如:  
  发送“A”到某号码,他将收到“回答正确”,  
  发送“B”到某号码,他收到“回答错误”,  
  而同样发送“A”,如果到别的号码,说不定就是“感谢参与”  
  ……  
   
  我的程序有接收、处理、发送三个线程。  
  接收线程收来的东西全部放进数据库,  
  处理线程则一个一个处理。  
  现在就说处理线程:  
   
   
  我用SELECT语句来选择没有处理过的记录,  
  ——某一个int型字段为0表示没有处理过,1表示已处理  
  于是,语句为“SELECT   ...   WHERE   (某字段   =   0)”,  
  为了防止长期占用资源,我每次只处理20条记录,然后等下一个时间。  
  于是我加了个“TOP   20”:“SELECT   TOP   20   ...   WHERE   (某字段   =   0)”,  
  为了有先有后,还要“ORDER   BY   某字段”,该字段就是有索引的ID号。  
  “SELECT   TOP   20   ...   WHERE   (某字段   =   0)   ORDER   BY   某ID字段”,  
   
  问题来了:  
   
  问题一,如果SELECT语句中包含有“TOP   20”,那么eof永远为假,  
  于是,“while   (!对象.Eof())”失败,  
  无法用这样的循环来一个一个处理。  
  目前我只好妥协了,去掉了“TOP   20”,  
  不含“TOP   20”的语句,其记录集会正确指示EOF状态。  
   
  去掉了“TOP   20”后,返回的记录集有可能会超过20条记录,  
  当然,也可能小于20条,甚至没有记录。  
  即使超过20,我也只处理20条:  
  我用“while   ((!对象.Eof())   &&   (iCount   <   20))”。  
   
  这样的改动,区别在于返回的记录集可能存在浪费。  
  有的时候,短时间内会有大量短信到达,  
  ——比如电视里公布题目的时候。  
  那么,SELECT语句一下子返回那么多记录,应该会浪费资源。  
   
   
  问题二、如果加了“ORDER   BY”,则记录无法更新。  
  我每处理一条记录,就要将那个特定的字段设为1,  
  表示这个记录已经处理过了,  
  但是,有“ORDER   BY”的查讯,这个操作失败。  
  您别问我记录集的锁定类型,它是正确的。  
   
  我又只好妥协了,去掉了“ORDER   BY”,不管它的先后,我就这么处理吧。  
  ——我觉得默认情况应该是按这个有索引的ID排的。  
  即使不是按ID排列的,问题也不大,先后不过相差零点几秒而已。  
   
  问题三、对于ACCESS,RecordCount可以返回正确的记录数,  
  对于SQL   SERVER,则永远返回-1,  
  所以,while(i<RecordCount)这种方式也不能循环。  
  还是只能用上面的循环方式:“while   ((!对象.Eof())   &&   (iCount   <   20))”。  
   
  这些问题以前一直没有碰到,  
  最初,我是专门写WEB程序的,ASP中没有碰到过这个问题,  
  后来,我写C++程序,用的是ACCESS也没有这个问题。  
  也就是说,ASP中操作ACCESS或SQL   SERVER都没有这个问题,  
  C++中操作ACCESS也没问题,  
  C++中操作SQL   SERVER就有以上两个问题。  
   
  短信处理程序用ASP这样的脚本是不够的,  
  ACCESS这样的数据库也不够。  
   
  -----------------------------  
  我的部分代码:  
  CoInitialize(NULL);//初始化COM环境  
  strConnectionString.Format("Provider=Sqloledb;User   ID=%s;Password=%s;Initial   Catalog=%s;Data   Source=%s;",  
      m_sSqlUsername,  
      m_sSqlPassword,  
      m_sSqlDatabaseName,  
      m_sSqlServerName);  
   
  try  
  {  
      m_pConn.CreateInstance(__uuidof(Connection));  
      m_pConn->PutConnectionTimeout(m_nTimeOut);  
      m_pConn->Open((_bstr_t)strConnectionString,  
          (_bstr_t)"",  
          (_bstr_t)"",  
          adModeUnknown);  
   
      m_pRs.CreateInstance(__uuidof(Recordset));  
      m_pRs->Open((_variant_t)m_strSql,  
          m_pConn.GetInterfacePtr(),  
          adOpenStatic,//3  
          adLockPessimistic,//2  
          adCmdText);  
  }  
   
   
  问题点数:20、回复次数:6Top

1 楼fcuandy(了此残生.)回复于 2006-07-03 01:38:34 得分 0

本來看題目都沒太明白,想著看一下代碼,一看是C++代碼,更暈了.只不過C++代碼看明白了卻還是沒明白樓主要干什麼.Top

2 楼toumao(偷猫)回复于 2006-07-03 10:49:26 得分 0

我认为我写的够详细的了。Top

3 楼longwycn((理想0769) ---要做DBA)回复于 2006-07-03 11:35:17 得分 20

我来答一下看:  
   
  第一:   top   20的问题是这样的,如果没到底。应该是不可以用EOF,  
  第二:   更新的SQL语句肯定是不可以Order   by   的,就算可以也没意思的。你只更新符合条件的纪录、  
   
  RecordCount   是可以返回实际的纪录数的。  
  Top

4 楼toumao(偷猫)回复于 2006-07-03 14:13:07 得分 0

奶奶个熊,是我的SQL   SERVER有问题,  
  我把我的程序给朋友测试,  
  在他那儿一切都好的。Top

5 楼playwarcraft(时间就像乳沟,挤挤还是有的)回复于 2006-07-03 14:26:47 得分 0

如果樓主用update   top   20   ..order   by的話,估計是會有問題的.  
  因為類似order   by   感覺上是一個temp   view,update的也許不是樓主想要的結果.  
   
  弱弱的想,樓主是否需要個臨時表放紀錄,可以把要處理的紀錄都insert到臨時表中,  
  這樣,收短信還是照收,每隔一段時間,把新收到的短信insert   into   臨時表裡去.  
  這樣,發送的時候,只要處理臨時表,不存在鎖定的問題,也不影響收信表了...Top

6 楼toumao(偷猫)回复于 2006-07-04 00:58:06 得分 0

下笔千言,离题万里。呵呵,  
  我说的明明白白,是Select,  
  居然扯到Update上了。  
   
  而且我还说了,同样的程序,给我朋友测试就没有这些问题,  
  是我的SQL   SERVER有问题。Top

相关问题

关键词

得分解答快速导航

  • 帖主:toumao
  • longwycn

相关链接

  • SQL Server类图书

广告也精彩

反馈

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