??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲狠狠婷婷综合久久,亚洲国产成人精品不卡青青草原,国产91在线|亚洲http://www.tkk7.com/jiangpingcmt1/zh-cnSun, 11 May 2025 13:59:43 GMTSun, 11 May 2025 13:59:43 GMT60sql执行序http://www.tkk7.com/jiangpingcmt1/archive/2012/08/10/385234.html火炎?/dc:creator>火炎?/author>Fri, 10 Aug 2012 07:58:00 GMThttp://www.tkk7.com/jiangpingcmt1/archive/2012/08/10/385234.htmlhttp://www.tkk7.com/jiangpingcmt1/comments/385234.htmlhttp://www.tkk7.com/jiangpingcmt1/archive/2012/08/10/385234.html#Feedback0http://www.tkk7.com/jiangpingcmt1/comments/commentRss/385234.htmlhttp://www.tkk7.com/jiangpingcmt1/services/trackbacks/385234.htmlSQL 不同于与其他~程语言的最明显特征是处理代码的序。在大数~程语言中,代码按编码顺序被处理Q但是在SQL语言中,W一个被处理的子句是FROM子句Q尽SELECT语句W一个出玎ͼ但是几乎L最后被处理?

      每个步骤都会(x)产生一个虚拟表Q该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)(j)不可用。只是最后一步生成的表才?x)返?l调用者。如果没有在查询中指定某一子句Q将跌相应的步骤。下面是对应用于SQL server 2000和SQL Server 2005的各个逻辑步骤的简单描q?/p>

复制代码
(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
(
1)FROM [left_table]
(
3)<join_type> JOIN <right_table>
(
2)ON <join_condition>
(
4)WHERE <where_condition>
(
5)GROUP BY <group_by_list>
(
6)WITH <CUBE | RollUP>
(
7)HAVING <having_condition>
(
10)ORDER BY <order_by_list>
复制代码

逻辑查询处理阶段?/strong>

  1. FROMQ?/strong>对FROM子句中的前两个表执行W卡?dng)积QCartesian product)(交叉联接Q,生成虚拟表VT1
  2. ONQ?/strong>对VT1应用ON{选器。只有那些<join_condition>为真的行才被插入VT2?/li>
  3. OUTER(JOIN)Q?/strong>?果指定了(jin)OUTER JOINQ相对于CROSS JOIN ?INNER JOIN),保留表(preserved tableQ左外部联接把左表标Cؓ(f)保留表,叛_部联接把双标记Z留表Q完全外部联接把两个表都标记Z留表Q中未找到匹配的行将作ؓ(f)外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表Q则对上一个联接生成的l果表和下一个表重复执行步骤1到步?Q直到处理完所有的表ؓ(f)止?/li>
  4. WHEREQ?/strong>对VT3应用WHERE{选器。只有<where_condition>为true的行才被插入VT4.
  5. GROUP BYQ?/strong>按GROUP BY子句中的列列表对VT4中的行分l,生成VT5.
  6. CUBE|ROLLUPQ?/strong>把超l?Suppergroups)插入VT5,生成VT6.
  7. HAVINGQ?/strong>对VT6应用HAVING{选器。只有<having_condition>为true的组才会(x)被插入VT7.
  8. SELECTQ?/strong>处理SELECT列表Q生VT8.
  9. DISTINCTQ?/strong>重复的行从VT8中移除,产生VT9.
  10. ORDER BYQ?/strong>VT9中的行按ORDER BY 子句中的列列表排序,生成游标QVC10).
  11. TOPQ?/strong>从VC10的开始处选择指定数量或比例的行,生成表VT11,q返回调用者?

注:(x)步骤10Q按ORDER BY子句中的列列表排序上步返回的行,q回游标VC10.q一步是W一步也是唯一一步可以用SELECT列表中的列别名的步骤。这一步不同于其它步骤?是,它不q回有效的表Q而是q回一个游标。SQL是基于集合理论的。集合不?x)预先对它的行排序,它只是成员的逻辑集合Q成员的序无关紧要。对表进行排?的查询可以返回一个对象,包含按特定物理顺序组l的行。ANSI把这U对象称为游标。理解这一步是正确理解SQL的基?/p>

因ؓ(f)q一步不q回表(而是q回游标Q,使用?jin)ORDER BY子句的查询不能用作表表达式。表表达式包括:(x)视图、内联表值函数、子查询、派生表和共用表辑ּ。它的结果必返回给期望得到物理记录的客L(fng)应用E序。例如,下面的派生表查询无效Qƈ产生一个错误:(x)

select * 
from(select orderid,customerid from orders order by orderid)
as d

下面的视图也?x)生错?/p>

create view my_view
as
select
*
from orders
order by orderid

      在SQL中,表表辑ּ中不允许使用带有ORDER BY子句的查询,而在T—SQL中却有一个例外(应用TOP选项Q?/p>

      所以要CQ不要ؓ(f)表中的行假设M特定的顺序。换句话_(d)除非你确定要有序行,否则不要指定ORDER BY 子句。排序是需要成本的QSQL Server需要执行有序烦(ch)引扫描或使用排序q行W?br />



]]>
CMPP2.0开?/title><link>http://www.tkk7.com/jiangpingcmt1/archive/2012/07/19/383460.html</link><dc:creator>火炎?/dc:creator><author>火炎?/author><pubDate>Wed, 18 Jul 2012 17:46:00 GMT</pubDate><guid>http://www.tkk7.com/jiangpingcmt1/archive/2012/07/19/383460.html</guid><wfw:comment>http://www.tkk7.com/jiangpingcmt1/comments/383460.html</wfw:comment><comments>http://www.tkk7.com/jiangpingcmt1/archive/2012/07/19/383460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jiangpingcmt1/comments/commentRss/383460.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jiangpingcmt1/services/trackbacks/383460.html</trackback:ping><description><![CDATA[<h1 class="postTitle"><a id="cb_post_title_url" class="postTitle2" >CMPP2.0开?/a></h1> <div class="yupsube" id="cnblogs_post_body"> <div>一、CMPP协议?/div> <div>中国Ud通信互联|短信网x口协?China Mobile Peer to Peer CMPP)Q是中国Ud梦网内部各SMS参与节点怺交换SMS的官方协议。作为梦|的参与方,Ud梦网的增值服务商(Service Provider SP )要按照此协议规范实现SP的部分,才可以将自己的短信通过Ud的GSM|络的数据通道传输到最l手机用户上?/div> <div>实际上,协议规范?个方面的内容Q?/div> <div>。SP与移动的互联|短信网养IInternet Short Message Gateway,ISMGQ之间的接口协议</div> <div>。ISMG之间的接口协议(譬如Ud各省、市(jng)之间的短信息交换通过ISMG之间q行Q?/div> <div>。ISMG与汇接网?Gateway Name Server GNSQ类g联网上的DNS服务?之间的接口协议,譬如跨省之类的短信需要GNS的帮助指出当前ISMG该如何传递短信?/div> <div>其中Q后二方面属于移动短信息pȝ内部实现Q对于SP来讲大概可以“透明”来看待,只要实现?jin)SP同ISMG的正交互,可以实现接入移动梦|短信系l。我们关?j)的只是SP端的开发细节?/div> <div></div> <div>二、CMPP交互模式</div> <div>从手机用戯度讲Q按短信的发?接收路径来讲Q有两个叫法Q?/div> <div><strong>MT</strong>(Short Message Mobile Terminated, SMMT)Q短信接Ӟ短信从SP发送到手机用户?/div> <div><strong>MO</strong> (Short Message Mobile OriginateQSMMO)Q短信发送,短信从手机用L(fng)发送到目标SP?/div> <div>q两cȝ信交互,从SP端来看,都是属于Socket传输应用QCMPP的协议是以TCP/IP协议作ؓ(f)底层承蝲协议的,属于TCP/IP协议栈之上的应用?/div> <div>SP同ISMG的交互连接分<strong>长连?/strong>?strong>短连?/strong>?/div> <div>所谓短q接Q就是一ơ连接,传输一个消息,然后{待回复后拆除连接,昄Q效率很低,所以,基本上不被考虑Q实际应用移动也不允许SP采用短连接,只是不明白移动ؓ(f)什么还要写入文档? ISMG间会(x)需要?Q?/div> <div>所谓长q接Q就是SP建立同ISMGq接Q然后不断将数据包(一个个CMPP消息Q发送到ISMGQ此处发送不必等待某条消息的ISMG回应消息q回Q就接着发送下一个消息。同Ӟ{待ISMGq回信息或者等待ISMG发送给SP的消息。发送同接收消息不是一定要同步的,实际采用异步Q同时也时双工)(j)模式。从效率上,昄Q必d双工的异步模式才能够满实际应用需求?/div> <div>如下图(摘自<a >CMPP2.0</a>官方文档Q所C,演示?jin)长q接模式数据传输q程Q?/div> <div> </div> <div> <img border="0" hspace="0" alt="" align="baseline" src="http://sg.kehui.net/articleimg/58809.jpg" /></div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div><br clear="all" /> <div>三、SP端开?/div> <div>1.         消息分类</div> <div>首先Q图中的CMPP消息有很多种QSP同ISMG之间交流q些消息。大体上q些消息发出后,Ҏ(gu)往往需要回复一个应{(RESPQ类消息。注意,q些消息大多h方向性,也就是说只能够从一端到另一端,而不可反方向q行Q有些(数Q则可两端都能够发出。以下信息主要来源于Ud的文档,但针对大家易h或源文档解释不够详细做了(jin)明确和补充。具体见下表Q?/div> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="191"> <div>       消息?/div></td> <td valign="top" width="93"> <div>传递方?/div></td> <td valign="top" width="228"> <div>解释说明</div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP­_CONNECT</div></td> <td valign="top" width="93"> <div>SP---àISMG</div></td> <td valign="top" width="228"> <div>CMPP_CONNECT操作的目的是SP向ISMG注册作ؓ(f)一个合法SPw䆾Q此消息需要向ISMG发出验证信息Q验证方式采用md5加密密码方式Q若注册成功后即建立?jin)应用层的连?否则ISMG?x)立x开Socket)Q此后SP可以通过此ISMG接收和发送短信?/div> <div>ISMG以CMPP_CONNECT_RESP消息响应SP的请求。具体的法实现参?a >CMPP2.0</a>文档和本文附件代码?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_CONNECT_RESP</div></td> <td valign="top" width="93"> <div>SPß---ISMG</div></td> <td valign="top" width="228"> <div>ISMG对CMPP_CONNECT消息的回复(无论是否验证成功Q;如果未通过Q会(x)在消息中包含参考信息,但ISMG?x)立x开q接?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP­_ACTIVE_TEST</div></td> <td valign="top" width="93"> <div>SPßàISMG</div></td> <td valign="top" width="228"> <div>q个消息通信双方都可以发出,目的是在没有其他消息发送时Q保持双方的通信链\的连接,避免pȝ认ؓ(f)通信通道已经关闭。每一个收到此消息的实体应当返回CMPP_ACTIVE_TEST_RESP消息Q以“CD?#8221;表示自己的还在通信Q维持数据连接有效性?/div> <div>不过Q据|友交流Q有些厂家实现的ISMGQ仅仅靠自己发出此消息等待SP回答CMPP_ACTIVE_TEST_RESP来确定数据链路的有效性,而忽略SP的CMPP_ACTIVE_TEST消息Q有些霸道吧Q)(j)q个值得注意Q不要仅仅实现发送而不响应此消息,避免数据q接失效?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_ACTIVE_TEST_RESP</div></td> <td valign="top" width="93"> <div>SPßàISMG</div></td> <td valign="top" width="228"> <div>寚w信的另一端的CMPP_ACTIVE_TEST消息的回复。作用参考CMPP_ACTIVE_TEST的解释?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP­_SUBMIT</div></td> <td valign="top" width="93"> <div>SP---àISMG</div></td> <td valign="top" width="228"> <div>在正徏立了(jin)数据q接后,SP向ISMG发送一个SMS数据包。本消息需要仔l研I。接收到此消息后QISMG需要以CMPP_SUBMIT_RESP消息作ؓ(f)回答。如果在一定时间时间内Q移动给出的参考?0U)(j)内未得到消息回应Q那么SP需要重新发送此数据包,以确保消息得到投递。如果重发达?ơ后仍然得不到回应,SP端应该考虑可能ISMG已经失效Q应当停止发送此短消息?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP­_SUBMIT_RESP</div></td> <td valign="top" width="93"> <div>SPß---ISMG</div></td> <td valign="top" width="228"> <div>该消息由ISMG发送给SPQ同时返回一?#8220;收条”(源CMPP_SUBMIT消息的ISMG端的标示MSGID)lSPQ表C?#8220;我ISMG已经认收到你这条消息了(jin)”。收到此消息后,SP需要保留此“收条”Q因为后面ISMG?x)最l报告本消息是否正确发送到用户手机。那个报告就是以此消息的“收条”作ؓ(f)认那一条消息的?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_QUERY</div></td> <td valign="top" width="93"> <div>SP---àISMG</div></td> <td valign="top" width="228"> <div>q个查询不是查询单条消息的,是查询SP发送给ISMG的短信的业务情况。可以查总计敎ͼq可以分cL询。(基本是发v对移动sms业务数据库的查询l计Q?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_QUERY_RESP</div></td> <td valign="top" width="93"> <div>SPß---ISMG</div></td> <td valign="top" width="228"> <div>ISMG查询的数据q回lSP?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_CANCEL</div></td> <td valign="top" width="93"> <div>SP---àISMG</div></td> <td valign="top" width="228"> <div>SP发v的取消某条消息的命o(h)消息Q其中包含了(jin)之前已经发送给ISMG消息?#8220;收条”以便ISMG可以定是那一条消息。如果消息已l发送给用户?jin),那么此消?命o(h)?x)无效,ISMGq回p|?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_CANCEL_RES</div></td> <td valign="top" width="93"> <div>SPß---ISMG</div></td> <td valign="top" width="228"> <div>ISMGq回的对CMPP_CANCEL的回复,q告知是否删除成功?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_DELIVER</div></td> <td valign="top" width="93"> <div>SPß---ISMG</div></td> <td valign="top" width="228"> <div>当有MO或者状态报告时QISMG发送此消息。注意,此消息的数据可以是用h机发送给SP的消息,也可是对于之前SP发送到ISMG的短信的最l状态的回复Q报告短信的最l状态?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_DELIVER_RESP</div></td> <td valign="top" width="93"> <div>SP---àISMG</div></td> <td valign="top" width="228"> <div>SPCD性的回复告知收到CMPP_DELIVER消息。要指出SP报告的CMPP_DELIVER消息的MSGIDQ以便ISMG知道那一条消息SP已经认收到?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP_TERMINAT</div></td> <td valign="top" width="93"> <div>SPßàISMG</div></td> <td valign="top" width="228"> <div>SP和ISMG都可以主动发消息l对方,自己q端׃某种原因需要终止当前的数据q接。终止后Q要l过重新ConnectionQ验证)(j)之后才可以(q入事务阶段Q发送SMS数据消息?/div></td></tr> <tr> <td valign="top" width="191"> <div>CMPP­_TERMINATE_RES</div></td> <td valign="top" width="93"> <div>SPßàISMG</div></td> <td valign="top" width="228"> <div>通知Ҏ(gu)Q本端已l最好撤除连接的准备?/div></td></tr></tbody></table> <div>                     </div> <div>2.         交互阶段</div> <div>整个CMPP协议交互分ؓ(f)<strong>验证</strong>?strong>事务</strong>两个阶段。验证阶D,发送CMPP_CONNECTION消息q行验证Q通过验证后(必须要通过才)(j)q入CMPP事务阶段Q可以发送短信数据了(jin)。上表中的CMPP_CONNECTION以下的消息都属于事务阶段的消息?/div> <div> </div> <div>3.         消息数据l构</div> <div>每一个消息包?<strong>消息?/strong> ?<strong>消息?/strong>两个部分Q头固定长度?2字节Q其他消息长度各异,但是同一cd消息的长度是固定的。所有消息的各个字段基本上仅?U类型:(x)Unsigned Integer Q无W号整型Q? 、IntegerQ整型)(j)、Octet StringQ字W串Q,每种cd具体长度不定Q网l字节顺序?/div> <div>1?nbsp; 消息?3个Unsigned Integer字段l成)Q?/div> <div>4字节的Total_Length QUnsigned IntegerQ,包含?jin)此消息的总计Q包括了(jin)头部分)(j)长度?/div> <div>4字节的Command_IdQUnsigned IntegerQ,指明?jin)此消息到底是什么消息,是上表中消息的枚D倹{应用程序根据此值确定本数据包到底是什么消息,从而可以按照确定的消息cdQ解析余下的消息体?/div> <div>4字节的Sequence_IdQUnsigned IntegerQ,指明?jin)此数据包在发送此消息端的唯一~号。这个唯一~号Q实际上可以看作水操作~号。因为分析到交互模式我们看到QSP发送数据到ISMGQ不是每发送一个就停下来等待ISMG的回复,而是“一下子”发送多个数据包q去Q然后等待ISMG的回应。然而,怎么知道回应的消息是到底对应之前发送过ȝ消息中的那一条呢Q本字段是解决此难题。SP按照~号发送消息过去,{待ISMG的回?#8212;一般情形下回应消息数据l构都有表明本消息回应的是SP发出的哪一条消息,q个对应是依靠Sequence_Id。它q不要求一定要严格唯一Q但是在l定的一D|间内Q必d一Q基本上只要SP发送过ȝ消息中没有重复就行了(jin)Q。如果是需要SP回答的消息,SP也必dISMG发送过来的消息的Sequence_Id填入相应字段Q表明这是某个消息的回应。SP端和ISMG端Sequence_ID都没有确定具体的法。SP可以(但不推荐)采用数据库的唯一Id作ؓ(f)此倹{?/div> <div> </div> <div>2、消息体。消息体长度Ҏ(gu)消息不同Q长度不一。其他的参考移动的文档《中国移动通信互联|短信网x口协?China Mobile Peer to Peer, CMPP)QV2.0Q》,q里着重讲?个重要消息的消息体数据结构:(x)</div> <div>       CMPP­_SUBMIT的消息体Q?/div> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="96"> <div>字段?/div></td> <td valign="top" width="48"> <div>长度(byte)</div></td> <td valign="top" width="84"> <div>cd</div></td> <td valign="top" width="264"> <div>描述</div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Id</div></td> <td valign="top" width="48"> <div>8</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>信息标识Q应该由SP侧ISMG本n产生Q本处填I,供ISMG传输时用。SP提交时候应当留I?/div></td></tr> <tr> <td valign="top" width="96"> <div>Pk_total</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>相同Msg_Id的信息L敎ͼ?开始。如果一条消息长度超多一条短信,可能需要分解成多条消息Q那么实际上q多条消息属于一条完整消息,所以可以根据此l分解得到的多条短信q行~号Q那么总计需要编成多条短信Q此处就填写多少?/div> <div> </div></td></tr> <tr> <td valign="top" width="96"> <div>Pk_number</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>相同Msg_Id的信息序P?开始。编号决定消息的相对位置?/div></td></tr> <tr> <td valign="top" width="96"> <div>Registered_Delivery</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>是否要求q回状态确认报告:(x)</div> <div>0Q不需?/div> <div>1Q需?/div> <div>2Q生SMC话单Q该cd短信仅供|关计费使用Q不发送给目的l端Q?/div> <div>一般情况下Q都需要确认报告。SMC话单也需要返回是否成功的报告。这条消息用于包月SMCӞ当你发送消息给Ud的ISMGQ移动的计费pȝ?x)一ơ性扣除用L(fng)信息费,但是此消息不?x)送到用户手机。但是注意,有的ISMG厂商(很可能是Ud要求)实现此消息时候,如果你ƈ没有发送Q何此包月cd的消息给用户手机Q是不发生扣费行为的。移动会(x)认ؓ(f)q是属于q规?#8220;代收?#8221;行ؓ(f)Q会(x)影响同移动的合作关系?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_level</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>信息U别Q信息的优先U。不q实际当中,感觉ISMG端ƈ没有区分优先U?/div></td></tr> <tr> <td valign="top" width="96"> <div>Service_Id</div></td> <td valign="top" width="48"> <div>10</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>业务cdQ是数字、字母和W号的组合。这个表CZ务的字符串可以给发出的短信分cR通过此字D大U可以知道每个服务项目的业务量,有利于统计和计费以及(qing)l算?/div></td></tr> <tr> <td valign="top" width="96"> <div>Fee_UserType</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>计费用户cd字段</div> <div>0Q对目的l端MSISDN计费Q?/div> <div>1Q对源终端MSISDN计费Q?/div> <div>2Q对SP计费;</div> <div>3Q表C本字段无效Q对谁计费参见Fee_terminal_Id字段?/div></td></tr> <tr> <td valign="top" width="96"> <div>Fee_terminal_Id</div></td> <td valign="top" width="48"> <div>21</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>被计费用L(fng)L(fng)Q如本字节填I,则表C本字段无效Q对谁计费参见Fee_UserType字段Q本字段与Fee_UserType字段???时互斥)(j)</div></td></tr> <tr> <td valign="top" width="96"> <div>TP_pId</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div align="left">GSM协议cd。详l是解释请参考GSM03.40中的9.2.3.9</div></td></tr> <tr> <td valign="top" width="96"> <div>TP_udhi</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div align="left">GSM协议cd。详l是解释请参考GSM03.40中的9.2.3.23,仅?位,叛_?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Fmt</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>信息格式</div> <div>  0QASCII?/div> <div>  3Q短信写卡操?/div> <div>  4Q二q制信息</div> <div>  8QUCS2~码</div> <div>15Q含GB汉字  </div> <div>q个军_?jin)Msg_Content字段的字节内容应该按照什么编码来解码/~码?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_src</div></td> <td valign="top" width="48"> <div>6</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>信息内容来源(SP的企业代?Q例?19000?/div></td></tr> <tr> <td valign="top" width="96"> <div>FeeType</div></td> <td valign="top" width="48"> <div>2</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>资费cd</div> <div>01Q对“计费用户L(fng)”免费</div> <div>02Q对“计费用户L(fng)”按条计信息费</div> <div>03Q对“计费用户L(fng)”按包月收信息?/div> <div>04Q对“计费用户L(fng)”的信息费顶</div> <div>05Q对“计费用户L(fng)”的收Ҏ(gu)由SP实现?/div> <div>通常gؓ(f)02Q注意这是一个字W串Qƈ非整型?/div></td></tr> <tr> <td valign="top" width="96"> <div>FeeCode</div></td> <td valign="top" width="48"> <div>6</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div align="left">资费代码Q以分ؓ(f)单位Q,如:(x)“0050”代表人民?.50元?/div></td></tr> <tr> <td valign="top" width="96"> <div>ValId_Time</div></td> <td valign="top" width="48"> <div>17</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>存活有效期,格式遵@SMPP3.3协议</div></td></tr> <tr> <td valign="top" width="96"> <div>At_Time</div></td> <td valign="top" width="48"> <div>17</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>定时发送时_(d)格式遵@SMPP3.3协议。这个字D可以让短信在规定的旉l手机用戗一般情况下不填Q保留ؓ(f)I字W串?/div></td></tr> <tr> <td valign="top" width="96"> <div>Src_Id</div></td> <td valign="top" width="48"> <div>21</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>源号?/div> <div>SP的服务代码或前缀为服务代码的长号? |关该L(fng)完整的填到SMPP协议Submit_SM消息相应的source_addr字段Q该L(fng)最l在用户手机上显CZؓ(f)短消息的dL(fng)。实际上是服务代码Q可以是长号?/div></td></tr> <tr> <td valign="top" width="96"> <div>DestUsr_tl</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>接收信息的用h?于100个用?Q通常?。移动是忌讳一条消息发l多个用L(fng)?/div></td></tr> <tr> <td valign="top" width="96"> <div>Dest_terminal_Id</div></td> <td valign="top" width="48"> <div>21*DestUsr_tl</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>接收短信的MSISDNL(fng)Q一个类似字W串数组的结构。受DestUsr_tl的约束,军_?jin)本字段的长度?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Length</div></td> <td valign="top" width="48"> <div>1</div></td> <td valign="top" width="84"> <div>Unsigned Integer</div></td> <td valign="top" width="264"> <div>信息长度(Msg_Fmtgؓ(f)0Ӟ(x)<160个字节;其它<=140个字?。如果是ASCII码,可以辑ֈ160个英文字母。原因是因ؓ(f)英文字母仅占?bitQ而中文等双字节代码需?6位,同时每一个字节最高ؓ(f)都占用,所以最?40个字节,也就?0个汉字?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Content</div></td> <td valign="top" width="48"> <div>Msg_length</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>信息内容</div></td></tr> <tr> <td valign="top" width="96"> <div>Reserve</div></td> <td valign="top" width="48"> <div>8</div></td> <td valign="top" width="84"> <div>Octet String</div></td> <td valign="top" width="264"> <div>保留</div></td></tr></tbody></table> <div>CMPP_SUBMIT消息长度是可变的Q将SP端的消息发送给ISMGQISMG返回一个MSGIDlSP标示此消息,之后Q?8时以内Q但一般最多几分钟内就可)(j)QISMGq回关于此消息的递送报告。递送报告同MO短消息是通过另外一个重要消息CMPP­_DELIVER来提交给SP的:(x)</div> <div>CMPP­_DELIVER的各个字D:(x)</div> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="96"> <div align="center">字段?strong></strong></div></td> <td valign="top" width="60"> <div align="center">字节?strong></strong></div></td> <td valign="top" width="96"> <div align="center">属?/div></td> <td valign="top" width="240"> <div align="center">描述<strong></strong></div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Id</div></td> <td valign="top" width="60"> <div>8</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>信息标识</div> <div>生成法如下Q?/div> <div>采用64位(8字节Q的整数Q?/div> <div>Q?Q时_(d)格式为MMDDHHMMSSQ即月日时分U)(j)Qbit64~bit39Q其?/div> <div>bit64~bit61Q月份的二进制表C;</div> <div>bit60~bit56Q日的二q制表示Q?/div> <div>bit55~bit51Q小时的二进制表C;</div> <div>bit50~bit45Q分的二q制表示Q?/div> <div>bit44~bit39Q秒的二q制表示Q?/div> <div>Q?Q短信网关代码:(x)bit38~bit17Q把短信|关的代码{换ؓ(f)整数填写到该字段中?/div> <div>Q?Q序列号Qbit16~bit1Q顺序增加,步长?Q@环用?/div> <div>各部分如不能填满Q左补零Q右寚w?/div></td></tr> <tr> <td valign="top" width="96"> <div>Dest_Id</div></td> <td valign="top" width="60"> <div>21</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>目的L(fng) </div> <div>SP的服务代码,一?--6位,或者是前缀为服务代码的长号码;该号码是手机用户短消息的被叫L(fng)?/div></td></tr> <tr> <td valign="top" width="96"> <div>Service_Id</div></td> <td valign="top" width="60"> <div>10</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>业务cdQ是数字、字母和W号的组合?/div></td></tr> <tr> <td valign="top" width="96"> <div>TP_pid</div></td> <td valign="top" width="60"> <div>1</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div align="left">GSM协议cd。详l解释请参考GSM03.40中的9.2.3.9</div></td></tr> <tr> <td valign="top" width="96"> <div>TP_udhi</div></td> <td valign="top" width="60"> <div>1</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div align="left">GSM协议cd。详l解释请参考GSM03.40中的9.2.3.23Q仅使用1位,叛_?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Fmt</div></td> <td valign="top" width="60"> <div>1</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>信息格式</div> <div>  0QASCII?/div> <div>  3Q短信写卡操?/div> <div>  4Q二q制信息</div> <div>  8QUCS2~码</div> <div>15Q含GB汉字   </div></td></tr> <tr> <td valign="top" width="96"> <div>Src_terminal_Id</div></td> <td valign="top" width="60"> <div>21</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>源终端MSISDNL(fng)Q状态报告时填ؓ(f)CMPP_SUBMIT消息的目的终端号码)(j)</div></td></tr> <tr> <td valign="top" width="96"> <div>Registered_Delivery</div></td> <td valign="top" width="60"> <div>1</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>是否为状态报?/div> <div>0Q非状态报告(MO SMSQ?/div> <div>1Q状态报?/div> <div>此字D决定了(jin)CMPP­_DELIVER消息到底是手Z行一条消息到SPq是ISMG向SP报告之前发送的消息最l递送状态?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Length</div></td> <td valign="top" width="60"> <div>1</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>消息长度。是指Msg_Content字段的长度?/div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Content</div></td> <td valign="top" width="60"> <div>Msg_length</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>消息内容。如果消息不是状态报告,那么按照Msg_Fmt指示解码为特定编码的字符串内宏V?/div></td></tr> <tr> <td valign="top" width="96"> <div>Reserved</div></td> <td valign="top" width="60"> <div>8</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>保留?/div></td></tr></tbody></table> <div>如果是报告,那么Msg_Content按照状态报告结构来解释Q?/div> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="96"> <div align="center">字段?strong></strong></div></td> <td valign="top" width="60"> <div align="center">字节?strong></strong></div></td> <td valign="top" width="96"> <div align="center">属?/div></td> <td valign="top" width="240"> <div align="center">描述<strong></strong></div></td></tr> <tr> <td valign="top" width="96"> <div>Msg_Id</div></td> <td valign="top" width="60"> <div>8</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>信息标识</div> <div>SP提交短信QCMPP_SUBMITQ操作时Q与SP相连的ISMG产生的Msg_Id?/div> <div>q个MSGID实际上就是SP之前发送一个CMPP_SUBMIT消息之后的CMPP_SUBMIT_RESP消息中返回的关于CMPP_SUBMIT消息的ISMG~号.Q根据此MSGID可以知道那条消息最l确定的递送状态?/div></td></tr> <tr> <td valign="top" width="96"> <div>Stat</div></td> <td valign="top" width="60"> <div>7</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>发送短信的应答l果Q含义与SMPP协议要求中stat字段定义相同Q详见下面。SPҎ(gu)该字D늡定被报告的CMPP_SUBMIT消息的处理状态?/div></td></tr> <tr> <td valign="top" width="96"> <div>Submit_time</div></td> <td valign="top" width="60"> <div>10</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>YYMMDDHHMMQYY为年的后两位00-99QMMQ?1-12QDDQ?1-31QHHQ?0-23QMMQ?0-59Q?/div></td></tr> <tr> <td valign="top" width="96"> <div>Done_time</div></td> <td valign="top" width="60"> <div>10</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>YYMMDDHHMM</div></td></tr> <tr> <td valign="top" width="96"> <div>Dest_terminal_Id</div></td> <td valign="top" width="60"> <div>21</div></td> <td valign="top" width="96"> <div>Octet String</div></td> <td valign="top" width="240"> <div>目的l端MSISDNL(fng)(SP发送CMPP_SUBMIT消息的目标终?</div></td></tr> <tr> <td valign="top" width="96"> <div>SMSC_sequence</div></td> <td valign="top" width="60"> <div>4</div></td> <td valign="top" width="96"> <div>Unsigned Integer</div></td> <td valign="top" width="240"> <div>取自SMSC发送状态报告的消息体中的消息标识?/div></td></tr></tbody></table> <div>关于State字段Q如下解释:(x)</div> <table border="1" cellspacing="0" cellpadding="0"> <tbody> <tr> <td valign="top" width="107"> <div>消息状态名</div></td> <td valign="top" width="149"> <div>最l状?/div></td> <td valign="top" width="224"> <div>描述</div></td></tr> <tr> <td valign="top" width="107"> <div>DELIVERED</div></td> <td valign="top" width="149"> <div>DELIVRD</div></td> <td valign="top" width="224"> <div>消息到达目标</div></td></tr> <tr> <td valign="top" width="107"> <div>EXPIRED</div></td> <td valign="top" width="149"> <div>EXPIRED</div></td> <td valign="top" width="224"> <div>消息q期</div></td></tr> <tr> <td valign="top" width="107"> <div>DELETED</div></td> <td valign="top" width="149"> <div>DELETED</div></td> <td valign="top" width="224"> <div>消息被删?/div></td></tr> <tr> <td valign="top" width="107"> <div>UNDELIVERABLE</div></td> <td valign="top" width="149"> <div>UNDELIV</div></td> <td valign="top" width="224"> <div>消息未被送达</div></td></tr> <tr> <td valign="top" width="107"> <div>ACCEPTED</div></td> <td valign="top" width="149"> <div>ACCEPTD</div></td> <td valign="top" width="224"> <div>消息被认?/div></td></tr> <tr> <td valign="top" width="107"> <div>UNKNOWN</div></td> <td valign="top" width="149"> <div>UNKNOWN</div></td> <td valign="top" width="224"> <div>未知状?/div></td></tr> <tr> <td valign="top" width="107"> <div>REJECTED</div></td> <td valign="top" width="149"> <div>REJECTD</div></td> <td valign="top" width="224"> <div>消息被弹?/div></td></tr></tbody></table> <div>其他消息l构Q具体说明见中移动的CMPP协议?/div> <div> </div> <div>4.         安全验证</div> <div>CMPP协议在CMPP_CONNECT中传递验证消息。验证消息ؓ(f)9字节?+Udl出的密?当前旉戛_节数l的MD5法后的字节。时间戳?月日时分U,10位。代码算法如下:(x)</div> <div>private byte[] getMd5Code()</div> <div>{</div> <div>       byte[] buf=new byte[6+9+_Password.Length+10] ;    </div> <div>       byte[] s_a=Encoding.ASCII.GetBytes(_SystemID); //是企业代码</div> <div>       byte[] s_0={0,0,0,0,0,0,0,0,0};     //9字节?,此处当作双0</div> <div>       byte[] s_p=Encoding.ASCII.GetBytes(_Password); //密码</div> <div>       this._timestamp =getTimestamp();    //取得认证码时赋值字W串</div> <div>       byte[] s_t=Encoding.ASCII.GetBytes(_timestamp); //10位字W串字节数组</div> <div>       s_a.CopyTo(buf,0);    </div> <div>       s_0.CopyTo(buf,6);   </div> <div>       s_p.CopyTo(buf,6+9);   </div> <div>       s_t.CopyTo(buf,6+9+_Password.Length); </div> <div>       MD5 md5= new MD5CryptoServiceProvider(); //创徏MD5cd</div> <div>       return(md5.ComputeHash(buf,0,buf.Length));</div> <div>}   </div> <div>其中getTimestamp函数回例?#8220;0710125959”Q??0?2?9?9U)(j)q样的字W串Q详l代码略q,有兴请查看本文的附件代码?/div> <div> </div> <div>5.         厂商API问题</div> <div>W者公司所处广东,q东Ud提供?jin)华为的以C 形式的APIQSMEIDLL.dllQ,来帮助大家初期熟(zhn)CMPP协议。但是,l过开发测试,发现华ؓ(f)的API臛_存在几个问题Q?/div> <div>1?nbsp; 装成几个API函数Q但是由于CMPP自n的复杂性,Dq些函数丑陋无比Q参数多Q而且难以明晰含义。华为的APIQ内部将CMPP的验证、事务阶D分成几个函数实玎ͼ其中发送SMS到ISMG功能以函数提供,竟然出现SubmitAExExEx之类的函数说明?/div> <div>2?nbsp; CMPP的交互是异步的,需要多U程实现一边发送,一Ҏ(gu)收反馈信息。此API应当是内部维护一个线E进行CMPP_SUBMIT消息发送,但是华ؓ(f)API却通过I@环之cȝ操作{待ISMGq回CMPP_SUBMIT_RESP得到相应的MSGID再返回(从而实现消息同步返回)(j)。经q测试,大约需?00毫秒Q这个在实际SP的高性能需求场合根本无法满系l要求?/div> <div>3?nbsp; 接收短信必须依靠E序d先发出函数HasDeliverMessage调用 Q得到有消息才可通过GetDeliverSMEx函数获取消息Q显?dng)q种方式是低效率的,而且Ҏ(gu)产生消息数据包丢失,表现为有些MO消息QSP接收不到。而且Qo(h)人疑惑的是,你还不能够新开一个线E专门来做判断ƈ接收MO的动作,实际开发中一旦采用线E来做就回发生内存保护错误(大概属于同API自n的线E有冲突Q?/div> <div>4?nbsp; q回错误码,往往又是华ؓ(f)自己定的一套错误码Q大概华计此APIZ(jin)适应SMGP CMPP{多个协议)(j)Q而且l常变动Q很是伤脑筋?/div> <div>Z以上理由Q我认ؓ(f)自己按照CMPP协议开发一个SP端程序,比较能够满一般SP的需求?/div> <div> </div> <div>四、C#实现</div> <div>1、CMPP协议实现cCMPPClient</div> <div>通过研究Q笔者用C#写了(jin)一l类实现自己的CMPP SP端程序(CMPPClientQ。ؓ(f)?jin)实现相关类Q还需要编写一些辅助类Qƈ且首先要解决CMPP协议的数据结构同C#的数据之间的转换问题?/div> <div>CMPP的Octet String 实际上相当于C#中的byte[]Q所有CMPP消息的Octet String字段Z(jin)CMPP_SUBMIT和CMPP_DELIVER的msg_content字段外,其他的都可以认ؓ(f)是ASCII~码Q所以全部可以采用System.Text.Encoding.ASCIIq行~码和解码;对于Msg_Content字段Q由于一般情况下存在汉字信息传输.Q所以默认的~?解码应该为Encoding.DefaultQ实际是什么编码还要考察MSG_Fmt字段指示正文到底是什么编码?/div> <div>对于Unsigned Integer 和Interger字段Q需要按照网l字节顺序和x86机器的字节编码顺序对照关p进行{换,具体我设计了(jin)一个工L(fng)提一些{换方法用:(x)</div> <div>public class BIConvert  //字节 整Ş 转换c?|络格式转换为内存格?/div> <div>       {</div> <div>              public static byte[] Int2Bytes(uint i)  //转换整Ş数据的网l次序字节数l?/div> <div>              {</div> <div>                     byte[] t=BitConverter.GetBytes(i) ;</div> <div>                     byte b=t[0];</div> <div>                     t[0]=t[3];</div> <div>                     t[3]=b;</div> <div>                     b=t[1];</div> <div>                     t[1]=t[2];</div> <div>                     t[2]=b;</div> <div>                     return(t);</div> <div>              }</div> <div> </div> <div>              public static uint Bytes2UInt(byte[] bs,int startIndex) //q回字节数组代表的整数数字,4个字节长度的数组</div> <div>              {</div> <div>                     byte[] t=new byte[4];</div> <div>                     for(int i=0;i<4 && i< bs.Length-startIndex ;i++)</div> <div>                     {</div> <div>                            t[i]=bs[startIndex+i];</div> <div>                     }  </div> <div>                     byte b=t[0];</div> <div>                     t[0]=t[3];</div> <div>                     t[3]=b;</div> <div>                     b=t[1];</div> <div>                     t[1]=t[2];</div> <div>                     t[2]=b;</div> <div>                     return(BitConverter.ToUInt32(t,0)); </div> <div>              } </div> <div> </div> <div>              public static uint Bytes2UInt(byte[] bs)  //没有指定起始索引</div> <div>              {</div> <div>                     return( Bytes2UInt(bs,0));</div> <div>              }</div> <div>       }</div> <div> </div> <div>其次Qؓ(f)?jin)实现收发数据?#8220;全双?#8221;Q需要设计至两个线E处理socket的读取和数据包写入。另外,Z(jin)自动实现Ҏ(gu)据链路的保持Q以?qing)自动实现数据包重发机|我还增加?jin)一个值守U程Q自动处理以上问题。详l见后代码。另外,消息中有很多同时间有关的字段Q但是这些时间相兛_Dƈ非按照统一规格~码的,q个需要仔l研I协议或者实C码?/div> <div>其三Qؓ(f)?jin)解?~码数据包方便,我将SP端涉?qing)到的消息以cȝ形式实现Q根据具体的消息cdQ将数据包字节解析还原ؓ(f)特定的消息;另一斚wQ当需要发送一些消息时Q将消息的各个字D,Ҏ(gu)cd和编码类?#8220;l装”成字节数l,以便Socket能够发送出厅R?/div> <div>其四Qؓ(f)?jin)达到?qing)时处理短消息的收发,我大量采用了(jin)C#事g触发来达到消息通知目的Q而且Q也设计一l事件参敎ͼ供事件的具体监听者可以掌握需要的信息?/div> <div>其五Q需要注意多U程间的同步问题?/div> <div>其六Q填写C(j)MPP_SUBMIT消息需要注意内容编码、计费字D|填?/div> <div> </div> <div>2、事件模?/div> <div>大体上实C(jin)十多个事Ӟq些事g具体为:(x)</div> <div>当CMPP_DELIVER消息送来的是短消息送达报告Ӟ发生消息送达报告事gQ?/div> <div>public delegate void <strong>ReportEventHandler</strong>(object sender, ReportEventArgs e);  <br />       当CMPP_DELIVER消息送来的是用户手机MO短消息时Q发生短信到达事Ӟ其他E序可以在处理此事g获得消息的正文、手机号码、SP服务L(fng){信息:(x)</div> <div>public delegate void <strong>SMSEventHandler</strong>(object sender, SMSEventArgs e);   <br />       当ISMG发出CMPP_TERMINATE消息Ӟ发生Q具体的回应Q我在具体实C先自动进行了(jin)回复Q生此事g仅仅向外部程序(此事件的截取者)(j)表达收到此消息,需要进?#8220;善后清场”操作Q?/div> <div>       public delegate void <strong>TerminateEventHandler</strong>(object sender,TerminateEventArgs e);   <br />              当SPdl止q接Ӟ发出CMPP_TERMINATE消息QISMG?x)响应CMPP_TERMINATE_RESP消息Q此事g表示收到此回?/div> <div>       public delegate void <strong>TerminateRespEventHandler</strong>(object sender,TerminateRespEventArgs e);  </div> <div>       以下两个事g针对链\保持消息CMPP_ACTIVE_TEST?qing)CMPP_ACTIVE_TEST_RESP发生Q?/div> <div>       public delegate void <strong>TestEventHandler</strong>(object sender,TestEventArgs e);</div> <div>       public delegate void <strong>TestRespEventHandler</strong>(object sender,TestRespEventArgs e);<br />       SP发出CMPP_CONNECT消息后,ISMG验证Q然后发出CMPP_CONNECT_RESP消息Q此时激zL事gQ?/div> <div>       public delegate void <strong>ConnectRespEventHandler</strong>(object sender,ConnectRespEventArgs e);</div> <div>       SP取消某条端消息,发出CMPP_CANCEL后,ISMG响应此消息返回CMPP_CANCEL_RESP消息ӞȀzMӞ(x)</div> <div>       public delegate void <strong>CancelRespEventHandler</strong>(object sender,CancelRespEventArgs e);<br />       SP提交短信后,ISMGq回一个CMPP_SUBMIT_RESP 消息Q包?#8220;收条”(MSG_ID)在内Q触发此事gQ?/div> <div>       public delegate void <strong>SubmitRespEventHandler</strong>(object sender,SubmitRespEventArgs e);</div> <div>       查询ISMGq回消息后,发生Q?/div> <div>       public delegate void <strong>QueryRespEventHandler</strong>(object sender,QueryRespEventArgs e);<br />       当SP验证通过后,作ؓ(f)应用逻辑需要得到通知Q我Ҏ(gu)加了(jin)此事Ӟ(x)</div> <div>       public delegate void <strong>LogonSuccEventHandler</strong>(object sender,EventArgs e); //当成功登录系l?/div> <div>       以下事gQ不是基于CMPP消息Q而是Ҏ(gu)SP同ISMG消息队列扫描后判断触发事Ӟ(x)</div> <div>       public delegate void <strong>SocketClosedEventHandler</strong>(object sender,EventArgs e); //当套接字被检到关闭</div> <div>       public delegate void <strong>FailedItemDeletedEventHandler</strong>(object sender,WaitingQueueItemEventArgs e); //当一条存在于{待队列的消息超q?0U没有回?/div> <div>以上q些事g~省实现保证?jin)SP端CMPP客户对于ISMG的响应自动化Q提供触发事件保证调用此客户端类的系l可以通过事g发生准确的控制SP端的内部状态,获取交互信息?/div> <div>另一斚wQ由于这些大多数事g发生于数据包辑ֈ后的处理Q实际上需要处理事件程序一定要“q?#8221;解决Q或者干脆将消息转换为可以暂存的消息形式Q由其他E序q一步处理。CMPP的SP端要满大量短信息应用需求,必M格控制消息交互处理逻辑不要太复杂,特别不要设计大量I/O处理Q如果实在要处理Q最好采用异步线E的方式来处理?/div> <div> </div> <div>3、ؓ(f)?jin)提高效率,开?个线E:(x)</div> <div>       RecvISMGMsgThread   用于处理接收ISMG发送过来的消息QƈҎ(gu)消息、消息解析后的字D内容触发相应的事g?/div> <div>       SendSPMsgThread        用于处理向ISMG发送数据包。注意,有些消息Q譬如CMPP_ACTIVE_TESTQ是pȝ自己产生的。另外,有些消息是收到ISMG的消息后需要立卛_应给ISMG的,那么q些消息Q全部进入内部维护的消息队列Q_outSeqQueueQ。该队列?x)自动排序消息,所有需要发送的消息Q进入此队列Q本U程不断从队列取出需要发送的消息Q{换成数据包,通过Socket发送到ISMG.</div> <div>       DeamonThread      用于监测数据q接socket是否可用Q是否需要发出维持数据连接的试数据包;有些消息发送过M(jin)Q过?jin)协议规定的旉仍然没有收到RESP消息Q那么需要将消息从已l发送的队列中提取,重新加入到发送队列中Q排队后{待送出?/div> <div>       可以仔细分析提供的代码,研究其中的具体实现?/div> <div> </div> <div>五、问题小l?/div> <div>Ҏ(gu)自己的经验,觉得以下几点对于整个pȝ开发较为重要:(x)</div> <div>1、一定要正确理解协议?/div> <div>很多|友交流时候,L怨协议滥Q搞不定Q其实很多原因属于自己没有清楚理解协议。从我的接触的移动ISMG来看Q应该说实现协议q是很严格遵守CMPP的描q。倒是Q一些网友自己开发的模拟器不是很规范Q不是批评,郑重声明Q,需要自己在开发时候引h意?/div> <div>2、多U程互斥问题?/div> <div>多个U程之间涉及(qing)一些队列的操作Q需要进行同步锁定,否则Ҏ(gu)引v问题。出现异怹需要及(qing)时捕Pq纪录作为错误信息参考,便于排除bug?/div> <div>3、自己控制数据包向和处理时间?/div> <div>׃设计目标是高性能Q所以在处理socket数据d时候要注意对于一些事件处理不要过多消耗系l资源,避免引v数据包来不及(qing)处理而导致数据丢失。特别在数据J忙时刻往往?x)ISMG的吞吐性能下降Q需要考虑对这U情况下的流量控制。有Ӟ你不能够指望ISMG如你所愿及(qing)时回应你Q更为常见的是ISMGҎ(gu)不返回RESPcd的数据包。另外,本协议处理数据收发采用阻塞SocketQ有|友我采用异步非dSocketQ我惛_能异步非dSocket?x)更好?/div> <div>4、服务监控问题?/div> <div>׃一些意外,往往?x)导致数据连接被中断Q这是,需要徏立超旉接的机制。我l出的例子ƈ未很好解冻I希望其他方家指正?/div> <div>5、字节顺序问题?/div> <div>q个问题Q对于初接触socket~程的h士往往造成很大ȝ(ch)。不q,CMPP协议设计的基本数据类型很单,仅需要按照本例子参考即可解冟?/div> <div>6、具体协议应用问题?/div> <div>本例仅仅是一个按照协议要求实现CMPP协议的类Q完整的SP端方案需要结合自己公司的实际要求Q改造或者重用本例。限于篇q,文中仅仅能够列出重点片断Q详l细节清参考供下蝲的代码(附注释)(j)。本文仅仅是针对<a >CMPP2.0</a>协议q行讨论开发,协议的详情请从移动梦|?http://www.monternet.com/moneditor/cs/SP/cmcc/)下蝲。其他技术参考可以到如下处获取,也可察看|友的脓(chung)字获取进一步详l说明:(x)</div> <div>       天堂鸟交论坛(<a >http://www.spzone.net/bbs/index.asp</a>Q?/div> <div>       CSDNC֌ Udq_<br />Qhttp://community.csdn.net/expert/forum.asp?url=/Expert/ForumsList.asp?roomid=63&typenum=1&whichpage=1Q?/div> <div>       SP论坛Qhttp://www.spforum.net/jishu/Index.aspQ?/div> <div>如果你发现本人的实例存在问题Q我想那直是一定的?jin)?j)Q请不吝赐教myjobsdk@yahoo.com.cn?/div> <div> </div> <div> 后记Q现在CMPP3?也就是移动的MISCq_版本的需要订购关pȝ定才可以计费。不q不是本文讨论的重点?/div></div><img src ="http://www.tkk7.com/jiangpingcmt1/aggbug/383460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jiangpingcmt1/" target="_blank">火炎?/a> 2012-07-19 01:46 <a href="http://www.tkk7.com/jiangpingcmt1/archive/2012/07/19/383460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>匿名内部c-回调Q闭?http://www.tkk7.com/jiangpingcmt1/archive/2011/11/24/364741.html火炎?/dc:creator>火炎?/author>Thu, 24 Nov 2011 08:44:00 GMThttp://www.tkk7.com/jiangpingcmt1/archive/2011/11/24/364741.htmlhttp://www.tkk7.com/jiangpingcmt1/comments/364741.htmlhttp://www.tkk7.com/jiangpingcmt1/archive/2011/11/24/364741.html#Feedback0http://www.tkk7.com/jiangpingcmt1/comments/commentRss/364741.htmlhttp://www.tkk7.com/jiangpingcmt1/services/trackbacks/364741.html首先明确闭包的概念:(x)一个代码段被用来做为方法的参数.
java中没有直接用某个方法做为另一个方法的参数的,java使用匿名内部cL模拟q种情况?/p>

匿名内部cd往是做Z个内部类Q接口)(j)的具体实现。在一些^台类Qplatform classQ中有一些模板方法。模板方法的包含?jin)固定流E。其中某些步骤是调用?jin)内部类Q接口)(j)中的某些Ҏ(gu)。但是^台类这些方法的具体实现延迟C(jin)业务cM。业务类调用q_cȝ模板Ҏ(gu)Q但是传入匿名内部类的实现做为模板方法的参数?

CZQ?/p>

 

package callback;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class AnonymousBusinessTemplateExample2 {

// 内部接口也是回调接口Q只定义抽象Ҏ(gu)?/span>
private interface Callback {
Object doIt(Connection conn)
throws SQLException;
}

// 模板Ҏ(gu)Q抽象)(j)
private Object execute(Callback callback) throws SQLException {
Connection conn
= openConnection();
try {
return callback.doIt(conn);
}
finally {
closeConnection(conn);
}
}

// 业务Ҏ(gu)(具体)
public Object sqlQuery(final String sql) throws SQLException {
//匿名内部cd为模板方法的参数来模拟闭?/span>
return execute(new Callback() {
public Object doIt(Connection conn) throws SQLException {
return conn.createStatement().executeQuery(sql);
}
});
}

public Connection openConnection() throws SQLException {
return DriverManager.getConnection("", null);
}

public void closeConnection(Connection conn) throws SQLException {
if (conn != null && !conn.isClosed()) {
conn.close();
}
}
}

 

 

 

一般内部接口比内部cȝ的更多。内部类中的Ҏ(gu)可以有默认的实现。匿名内部类做ؓ(f)业务Ҏ(gu)的参C入时Q会(x)override默认的方?/span>。内部接口的话,没有默认的实现。完全将具体的实Cl了(jin)匿名内部cR?/p>

匿名内部cȝ思想是回调,卛_茉坞原则?span style="color: #ff0000">回调的一个好处是decouple?/span> 客户端只需要关?j)业务(比如匿名内部cȝ具体实现Q而不用再兛_(j)一些资源的q接释放什么的Q这些交l^台类中的模板Ҏ(gu)。ruby的闭包还支持Ҏ(gu)l中的每个元素,文g中的每行Q结果集中的每个记录的操作。而用java实现q样?span style="color: #ff0000">q代q操作其中元?/span>非常ȝ(ch)。感觉java中用的多的偏模板Ҏ(gu)Q即逻辑中固定一些流E,初始化及(qing)释放某些资源?/p>




动态回调函数、匿名内部类和spring中的excuteҎ(gu)

    公司目前采用?jin)spring框架来构建和理整个web目。对于持久层的处理,使用?jin)由spring框架提供的对hibernate3的封装。这样做无非是ؓ(f)?jin)用spring提供的对事务的统一理。当我们用到由spring所装的hibernate的时候一定会(x)用到一个类QHibernateTemplate.q是一个对持久层处理封装的非常完整的类Q包括对session的管理(事实上session的获取于释放是一个o(h)人头疼的问题Q等{,我们通常?x)用HibernateTemplate的excuteҎ(gu)来进行数据库操作Q即使我们调用的也许是别的类gfind、get之类的方法,但是实质上最l还是{变ؓ(f)?jin)调用excuteҎ(gu)Q。对于第一ơ用这个方法一定会(x)存在困扰。因为excuteҎ(gu)所需要的参数一个HibernateCallbackcd的参数。而在excuteҎ(gu)体内部回调了(jin)HibernateCallbackcd的doInHibernateҎ(gu)。这是一个典型的对象回调。就到目前ؓ(f)止也怸切都很清晰。但是实际上如果阅读?jin)HibernateTemplate的内部代码就?x)发玎ͼ对于像get、findq样的方法最l都回调用excute来完成数据库操作但是调用形式看v来却很奇怪:(x)

public Object get(final Class entityClass, final Serializable id, final LockMode lockMode)

        throws DataAccessException

    {

        return execute(new HibernateCallback() {

            public Object doInHibernate(Session session)

                throws HibernateException

            {

                if(lockMode != null)

                    return session.get(entityClass, id, lockMode);

                else

                    return session.get(entityClass, id);

            }

        }, true);

    }

    ExcuteҎ(gu)的参数是一U匿名类的方式。ؓ(f)什么要采用匿名cdQ不怎么说匿名类看v来L让h觉得不舒服)(j)Q这个地Ҏ(gu)否必采用匿名类呢?

    首先我们来想一惌D代码涉?qing)到几个关键点?x)1、回调:(x)excuteҎ(gu)?x)回调HibernateCallbackcd的doInHibernateҎ(gu)Q?、匿名类参数Q我们ؓ(f)excuteҎ(gu)提供的参数ƈ不是一个真正生命出来的HibernateCallback实例?、动态创建回调方法:(x)如果我们打开HibernateCallbackcd?x)发玎ͼ其实q是一个abstractcd的类Q而他声明?jin)唯一的一个ie抽象Ҏ(gu)是doInHibernate。问题似乎已l明朗了(jin)Q如果不采用匿名c,我们需要做的是为HibernateCallback创徏一个实现类Qƈ且实现doInHibernateҎ(gu)。但是最要命的问题是doInHibernateҎ(gu)的实现对于我们的实际需求来说每一ơ调用可能都是不一L(fng)Q在doInHibernateҎ(gu)中我们用sessionq行数据库操作,对于不同的业务逻辑Q方法实现必定是不一L(fng)Q,采用?jin)匿名类我们不用在代码重创徏新的cdQ而且可以动态的创徏我们所需要的回调函数?/p>

    ȝ一下,我们上面所讲的q是如何用HibernateTemplateq个cR我们得到的l论是:(x)当我们需要动态的创徏回调函数的时候,匿名内部cL一个好的方式。注Q这U需要动态创建的回调Ҏ(gu)通常是一个interface中的接口或者abstract class中的抽象Ҏ(gu)?/p>




]]>
mina_包、多包和包的解x?http://www.tkk7.com/jiangpingcmt1/archive/2011/09/14/358594.html火炎?/dc:creator>火炎?/author>Wed, 14 Sep 2011 04:38:00 GMThttp://www.tkk7.com/jiangpingcmt1/archive/2011/09/14/358594.htmlhttp://www.tkk7.com/jiangpingcmt1/comments/358594.htmlhttp://www.tkk7.com/jiangpingcmt1/archive/2011/09/14/358594.html#Feedback0http://www.tkk7.com/jiangpingcmt1/comments/commentRss/358594.htmlhttp://www.tkk7.com/jiangpingcmt1/services/trackbacks/358594.html
不懈努力Q终于解决了(jin)。原来解x法是那样的简单。废话少_(d)L(fng)列子?
  
   另外Z(jin)一个交群Q?9702042Q大家可以在U交?

   问题Q我发送的是xml字符串数据,在发送数据后Q接收方在解码的时候可能接?条,也可能是多条Q还

可能是半条或一条半Q解x法就是用CumulativeProtocolDecoder

   首先Q在~码的时候要把前4位设成标志位Q标志消息内容的长度。里面的重点是doDecode的返回|一

定要l承CumulativeProtocolDecoder 哦?

   清看decode的写法:(x)
Java代码 复制代码 收藏代码
  1. public class AsResponseDecoder extends CumulativeProtocolDecoder {   
  2.     private static Logger LOG = LoggerFactory.getLogger(AsResponseDecoder.class);   
  3.     private final Charset charset;   
  4.        
  5.     public AsResponseDecoder(Charset charset){   
  6.         this.charset = charset;   
  7.     }   
  8.        
  9.   
  10.     /**  
  11.      * q个Ҏ(gu)的返回值是重点Q? 
  12.      * 1、当内容刚好Ӟq回falseQ告知父cL收下一批内? 
  13.      * 2、内容不够时需要下一批发q来的内容,此时q回falseQ这L(fng)c? 
  14.  
  15. CumulativeProtocolDecoder  
  16.      *    ?x)将内容放进IoSession中,{下ơ来数据后就自动D再交l本cȝdoDecode  
  17.      * 3、当内容多时Q返回trueQ因为需要再本Ҏ(gu)据进行读取,父类?x)将剩余的数据再ơ推送本  
  18.  
  19. cȝdoDecode  
  20.      */  
  21.     public boolean doDecode(IoSession session, IoBuffer in,   
  22.             ProtocolDecoderOutput out) throws Exception {   
  23.            
  24.         CharsetDecoder cd = charset.newDecoder();   
  25.         if(in.remaining() > 0){//有数据时Q读?字节判断消息长度   
  26.             byte [] sizeBytes = new byte[4];   
  27.             in.mark();//标记当前位置Q以便reset   
  28.             in.get(sizeBytes);//d?字节   
  29.                         //NumberUtil是自己写的一个int转byte[]的一个工L(fng)   
  30.             int size = NumberUtil.byteArrayToInt(sizeBytes);   
  31.             //如果消息内容的长度不够则直接q回true   
  32.             if(size > in.remaining()){//如果消息内容不够Q则重置Q相当于不读取size   
  33.                 in.reset();   
  34.                 return false;//接收新数据,以拼凑成完整数据   
  35.             } else{   
  36.                 byte[] bytes = new byte[size];    
  37.                 in.get(bytes, 0, size);   
  38.                 String xmlStr = new String(bytes,"UTF-8");   
  39.                 System.out.println("------------"+xmlStr);   
  40.                 if(null != xmlStr && xmlStr.length() > 0){   
  41.                     AsResponse resCmd = new AsResponse();   
  42.                     AsXmlPacker.parse(resCmd, xmlStr);   
  43.                     if(resCmd != null){   
  44.                         out.write(resCmd);   
  45.                     }   
  46.                 }   
  47.                 if(in.remaining() > 0){//如果d内容后还_了(jin)包,p父类再给?  
  48.   
  49. 一ơ,q行下一ơ解?  
  50.                     return true;   
  51.                 }   
  52.             }   
  53.         }   
  54.         return false;//处理成功Q让父类q行接收下个?  
  55.     }   
  56.   
  57.   
  58. }  

下面附上Encodec?
Java代码 复制代码 收藏代码
  1. public class AsResponseEncoder extends ProtocolEncoderAdapter {   
  2.     private final Charset charset;   
  3.        
  4.     public AsResponseEncoder(Charset charset){   
  5.         this.charset = charset;   
  6.     }   
  7.        
  8.     public void encode(IoSession session, Object message,   
  9.         ProtocolEncoderOutput out) throws Exception {   
  10.         CharsetEncoder ce = charset.newEncoder();   
  11.         IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);   
  12.            
  13.         AsResponse respCmd = (AsResponse) message;   
  14.            
  15.         String xml = AsXmlPacker.pack(respCmd);//对象{成xml   
  16.         byte[] bytes = xml.getBytes();   
  17.         byte[] sizeBytes = NumberUtil.intToByteArray(bytes.length);   
  18.            
  19.         buffer.put(sizeBytes);//前4位设|成数据体的字节长度   
  20.         buffer.put(bytes);//消息内容   
  21.         buffer.flip();   
  22.         out.write(buffer);   
  23.     }   
  24.   
  25.   
  26. }  

    JDK   ByteBuffer

     

    属性:(x)

    Mark

    上次position的快?/span>

    Position

    当前d索引未知

    Limit

    ~冲区限?/p>

    Capacity

    ~冲?/p>

    Offset

    偏移?/p>

     

    说明Q?/p>

    • Position(Mark)<=limit<=capacity
    • ?/span>position==limit时就没有字节可读写了(jin)
    • 每次get?/span>put都将增加position
    • 重置mark是讄mark=-1

     

     

    Ҏ(gu)Q?/p>

    Limit(int)

    如果position>limit, position = limit,如果mark>limit, 重置mark

    Mark()

    取当前的position的快?/span>标记mark

    Reset()

    恢复position到先前标记的mark

    Clear()

    limit=capacity , position=0,重置mark,但是不清I数据,Z(jin)从头开?/span>put做准备,其实是清空数据Q因Zputp盖了(jin)原来的数?/span>

    Rewind()

    position=0,重置mark,一pd写操作后Qؓ(f)?jin)从头开?/span>get做准备,?/span>clear()有用途上的区别,他大部分是用来从头开始读取,?/span>clear是大部分用来重头开始填充,是清理的意?/span>

    Flip()

    limit=position , position=0,重置maskQؓ(f)?jin)?/span>buf写出做好准备Q一般是l束buf操作Q将buf写入输出时调用Q这个必要调用Q否则极有可?/span>position!=limitQ导?/span>position后面没有数据Q每ơ写入数据到输出时Q必ȝ?/span>position=limit?/span>

    Remaining()

    q回limit-position,q回~冲器中的剩余字?/span>

    Wrap(byte[])

    l装到新?/span>bufferQ?/span>capacity=limit=byte[].lengthQ?/span>position=0 重置mark

    Slice()

    分割~冲器,?/span>remaining的空间Ş成一个新?/span>bufferQ新?/span>position=0Q?/span>limit=capacity=remainingQ重|?/span>markQ和ȝ冲区内容׃nQ其它都独立

    Duplicate()

    复制~冲区,内容׃nQ其它都独立

    asReadOnlyBuffer()

    和duplicate一P只是不可?/p>

    Compact()

    ?/span>position?/span>limit之间的字节移到最前面Q?/span>position=limit-positionQ这是q里的压~的意思,一般是l束buf操作Q将buf写入输出时调用

    Position(int)

    position=newPosition,如果position<mark,重置mark

    Remaining()

    q回position?/span>limit之间的字节数

 

 

JDK ByteBuffer

Mina IoBuffer

动态扩?/span>capacity

?/p>

?/p>

支持Stringd

?/p>

?/p>

U程安全

?/p>

?/p>

可主动释攄冲区占用内存

?/p>

?/p>



]]>
oracle sql 4?/title><link>http://www.tkk7.com/jiangpingcmt1/archive/2011/06/27/353044.html</link><dc:creator>火炎?/dc:creator><author>火炎?/author><pubDate>Sun, 26 Jun 2011 16:31:00 GMT</pubDate><guid>http://www.tkk7.com/jiangpingcmt1/archive/2011/06/27/353044.html</guid><wfw:comment>http://www.tkk7.com/jiangpingcmt1/comments/353044.html</wfw:comment><comments>http://www.tkk7.com/jiangpingcmt1/archive/2011/06/27/353044.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/jiangpingcmt1/comments/commentRss/353044.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/jiangpingcmt1/services/trackbacks/353044.html</trackback:ping><description><![CDATA[<ul><li><font size="2" face="Arial">如果存在更斎ͼ不存在就插入用一个语句实?/font> </li></ul> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #000000">MERGE </span> <span style="color: #0000ff">INTO</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> t_mg a<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />USING (</span> <span style="color: #0000ff">SELECT</span> <span style="color: #000000"> </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">the code</span> <span style="color: #ff0000">'</span> <span style="color: #000000"> code, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">the name</span> <span style="color: #ff0000">'</span> <span style="color: #000000"> NAME </span> <span style="color: #0000ff">FROM</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> dual) b<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">ON</span> <span style="color: #000000"> (a.code </span> <span style="color: #808080">=</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> b.code)<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">WHEN</span> <span style="color: #000000"> MATCHED </span> <span style="color: #0000ff">THEN</span> </font></font><span style="color: #000000"><br /><font size="2" face="Arial"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> </font></span><font face="Arial"><font size="2"><span style="color: #0000ff">UPDATE</span> <span style="color: #000000"> </span> <span style="color: #0000ff">SET</span> <span style="color: #000000"> a.NAME </span> <span style="color: #808080">=</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> b.NAME<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">WHEN</span> <span style="color: #000000"> </span> <span style="color: #808080">NOT</span> <span style="color: #000000"> MATCHED </span> <span style="color: #0000ff">THEN</span> </font></font><span style="color: #000000"><br /><font size="2" face="Arial"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> </font></span><font face="Arial"><font size="2"><span style="color: #0000ff">INSERT</span> <span style="color: #000000"> (code, NAME) </span> <span style="color: #0000ff">VALUES</span> <span style="color: #000000"> (b.code, b.NAME);</span> </font></font></div> <ul><li><font size="2" face="Arial">分页法 </font></li></ul> <p><font size="2" face="Arial"></font></p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #0000ff">SELECT</span> <span style="color: #000000"> </span> <span style="color: #808080">*</span> </font></font><span style="color: #000000"><br /><font size="2" face="Arial"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> </font></span><font face="Arial"><font size="2"><span style="color: #0000ff">FROM</span> <span style="color: #000000"> (</span> <span style="color: #0000ff">SELECT</span> <span style="color: #000000"> a.</span> <span style="color: #808080">*</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000">, ROWNUM rn<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">FROM</span> <span style="color: #000000"> (</span> <span style="color: #0000ff">SELECT</span> <span style="color: #000000"> </span> <span style="color: #808080">*</span> <span style="color: #000000"> </span> <span style="color: #0000ff">FROM</span> <span style="color: #000000"> t_employees </span> <span style="color: #0000ff">ORDER</span> <span style="color: #000000"> </span> <span style="color: #0000ff">BY</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> first_name) a<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">WHERE</span> <span style="color: #000000"> ROWNUM </span> <span style="color: #808080"><=</span> <span style="color: #000000"> </span> <span style="color: #800000; font-weight: bold">500</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000">)<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">WHERE</span> <span style="color: #000000"> rn </span> <span style="color: #808080">></span> <span style="color: #000000"> </span> <span style="color: #800000; font-weight: bold">480</span> <span style="color: #000000"> ;</span> </font></font></div> <p><font size="2" face="Arial"></font></p> <ul><li><font size="2" face="Arial">抽取/删除重复记录</font> </li></ul> <p><strong><font size="2" face="Arial">1) 部分字段重复数据的删?/font> </strong></p> <p><font size="2" face="Arial"></font></p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #0000ff">delete</span> <span style="color: #000000"> </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 表名 a <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">where</span> <span style="color: #000000"> a.rowid </span> <span style="color: #808080">!=</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />(<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">select</span> <span style="color: #000000"> </span> <span style="color: #ff00ff">max</span> <span style="color: #000000">(b.rowid) </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 表名 b <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">where</span> <span style="color: #000000"> a.字段1 </span> <span style="color: #808080">=</span> <span style="color: #000000"> b.字段1 </span> <span style="color: #808080">and</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />a.字段2 </span> <span style="color: #808080">=</span> </font></font><span style="color: #000000"><font size="2" face="Arial"> b.字段2 <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />)</font> </span></div> <p><font size="2" face="Arial">上面语句的执行效率是很低的,可以考虑建立临时表,讲需要判断重复的字段、rowid插入临时表中Q然后删除的时候在q行比较?br /></font></p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #0000ff">create</span> <span style="color: #000000"> </span> <span style="color: #0000ff">table</span> <span style="color: #000000"> 临时?nbsp;</span> <span style="color: #0000ff">as</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">select</span> <span style="color: #000000"> a.字段1,a.字段2,</span> <span style="color: #ff00ff">MAX</span> <span style="color: #000000">(a.ROWID) dataid </span> <span style="color: #0000ff">from</span> <span style="color: #000000"> 正式?nbsp;a </span> <span style="color: #0000ff">GROUP</span> <span style="color: #000000"> </span> <span style="color: #0000ff">BY</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> a.字段1,a.字段2;<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">delete</span> <span style="color: #000000"> </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 表名 a <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">where</span> <span style="color: #000000"> a.rowid </span> <span style="color: #808080">!=</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />(<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">select</span> <span style="color: #000000"> b.dataid </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 临时?nbsp;b <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">where</span> <span style="color: #000000"> a.字段1 </span> <span style="color: #808080">=</span> <span style="color: #000000"> b.字段1 </span> <span style="color: #808080">and</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />a.字段2 </span> <span style="color: #808080">=</span> </font></font><span style="color: #000000"><font size="2" face="Arial"> b.字段2 <br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" />)</font> </span></div> <p><strong><font size="2" face="Arial">2) 完全重复记录的删?/font> </strong></p> <p><font size="2" face="Arial">用下面语句获取到L重复数据后的记录Q?/font> </p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #0000ff">select</span> <span style="color: #000000"> </span> <span style="color: #0000ff">distinct</span> <span style="color: #000000"> </span> <span style="color: #808080">*</span> <span style="color: #000000"> </span> <span style="color: #0000ff">from</span> <span style="color: #000000"> 表名</span> </font></font></div> <p><font size="2" face="Arial">可以查询的记录攑ֈ临时表中Q然后再原来的表记录删除,最后将临时表的数据导回原来的表中。如下:(x)</font> </p> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font face="Arial"><font size="2"><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /> <span style="color: #0000ff">CREATE</span> <span style="color: #000000"> </span> <span style="color: #0000ff">TABLE</span> <span style="color: #000000"> 临时?nbsp;</span> <span style="color: #0000ff">AS</span> <span style="color: #000000"> (</span> <span style="color: #0000ff">select</span> <span style="color: #000000"> </span> <span style="color: #0000ff">distinct</span> <span style="color: #000000"> </span> <span style="color: #808080">*</span> <span style="color: #000000"> </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 表名);<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">drop</span> <span style="color: #000000"> </span> <span style="color: #0000ff">table</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 正式?<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">insert</span> <span style="color: #000000"> </span> <span style="color: #0000ff">into</span> <span style="color: #000000"> 正式?nbsp;(</span> <span style="color: #0000ff">select</span> <span style="color: #000000"> </span> <span style="color: #808080">*</span> <span style="color: #000000"> </span> <span style="color: #0000ff">from</span> </font></font><font face="Arial"><font size="2"><span style="color: #000000"> 临时?;<br /><img alt="" align="top" src="http://www.tkk7.com/Images/OutliningIndicators/None.gif" /></span> <span style="color: #0000ff">drop</span> <span style="color: #000000"> </span> <span style="color: #0000ff">table</span> <span style="color: #000000"> 临时?</span> </font></font></div><font size="2"><br />执行上记SQL语句,可以查寻到数据库中的锁的情报.</font><br /> <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><font size="2"><span style="color: #0000ff">SELECT</span> <span style="color: #000000">  S.SID SESSION_ID, S.USERNAME, DECODE(LMODE, </span> <span style="color: #800000; font-weight: bold">0</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">None</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">1</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Null</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">2</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Row-S (SS)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">3</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Row-X (SX)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">,  </span> <span style="color: #800000; font-weight: bold">4</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Share</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">5</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">S/Row-X (SSX)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">,  </span> <span style="color: #800000; font-weight: bold">6</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Exclusive</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, TO_CHAR(LMODE)) MODE_HELD, DECODE(REQUEST, </span> <span style="color: #800000; font-weight: bold">0</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">None</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">1</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Null</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">2</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Row-S (SS)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">3</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Row-X (SX)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">4</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Share</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">5</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">S/Row-X (SSX)</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, </span> <span style="color: #800000; font-weight: bold">6</span> <span style="color: #000000">, </span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">Exclusive</span> <span style="color: #ff0000">'</span> <span style="color: #000000">, TO_CHAR(REQUEST)) MODE_REQUESTED, O.OWNER</span> <span style="color: #808080">||</span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">.</span> <span style="color: #ff0000">'</span> <span style="color: #808080">||</span> <span style="color: #000000">O.</span> <span style="color: #ff00ff">OBJECT_NAME</span> <span style="color: #808080">||</span> <span style="color: #ff0000">'</span> <span style="color: #ff0000"> (</span> <span style="color: #ff0000">'</span> <span style="color: #808080">||</span> <span style="color: #000000">O.OBJECT_TYPE</span> <span style="color: #808080">||</span> <span style="color: #ff0000">'</span> <span style="color: #ff0000">)</span> <span style="color: #ff0000">'</span> </font><font size="2"><span style="color: #000000">, S.TYPE LOCK_TYPE, L.ID1 LOCK_ID1, L.ID2 LOCK_ID2 <br /></span><span style="color: #0000ff">FROM</span> </font><font size="2"><span style="color: #000000"> V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION S <br /></span><span style="color: #0000ff">WHERE</span> <span style="color: #000000"> L.SID </span> <span style="color: #808080">=</span> <span style="color: #000000"> S.SID </span> <span style="color: #808080">AND</span> <span style="color: #000000">  L.ID1 </span> <span style="color: #808080">=</span> <span style="color: #000000"> O.</span> <span style="color: #ff00ff">OBJECT_ID</span> </font></div><font size="2">SESSION_ID, USERNAME,  MODE_HELD,  MODE_REQUESTED, OBJECT_NAME, LOCK_TYPE, LOCK_ID<br />分别?拥有锁的SESSION_ID,拥有锁的USERNAME,锁的执行模式MODE_HELD,锁的hMODE_REQUESTED,锁所在的数据库对象名<br />,锁的cd,锁的ID<br /></font> <img src ="http://www.tkk7.com/jiangpingcmt1/aggbug/353044.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/jiangpingcmt1/" target="_blank">火炎?/a> 2011-06-27 00:31 <a href="http://www.tkk7.com/jiangpingcmt1/archive/2011/06/27/353044.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://yw8885.com" target="_blank">Ʒ1024</a>| <a href="http://aijiu868.com" target="_blank">aҹëƬһ</a>| <a href="http://mt181.com" target="_blank">ȾþǾƷ6ѹۿ</a>| <a href="http://aabbcc567.com" target="_blank">99ƷƵۿ</a>| <a href="http://jsky163.com" target="_blank">պƵһ </a>| <a href="http://jyzs888.com" target="_blank">һƷ</a>| <a href="http://v1s3u5.com" target="_blank">鵺̳Ƶ</a>| <a href="http://fantoment.com" target="_blank">97Ƶ</a>| <a href="http://yg1617.com" target="_blank">XX00Ƶ</a>| <a href="http://hzsprfm.com" target="_blank">AVר</a>| <a href="http://yinyinai155.com" target="_blank">þþþþþùѿ</a>| <a href="http://fsdyzs.com" target="_blank">ĻȫѰ</a>| <a href="http://www50884.com" target="_blank">һAV</a>| <a href="http://www4jbd.com" target="_blank">˳վ999þþۺ</a>| <a href="http://uu313.com" target="_blank">ӰӾ߹ۿȫ</a>| <a href="http://scdsrq.com" target="_blank">ŮëƬѹۿ97</a>| <a href="http://520baoyu.com" target="_blank">޳AVƬһ</a>| <a href="http://gysysz.com" target="_blank">gayˬˬƵ</a>| <a href="http://wwwee2.com" target="_blank">ԻȫƵվ</a>| <a href="http://tlyihong.com" target="_blank">˵һaվ</a>| <a href="http://343dd.com" target="_blank">պƷAV</a>| <a href="http://8aa3.com" target="_blank">ҹվ߹ۿۿ</a>| <a href="http://yctbhb.com" target="_blank">ý߹ۿƵѹۿ</a>| <a href="http://baocaoluoli.com" target="_blank">ƷպAV</a>| <a href="http://sdcwpfw.com" target="_blank">һ˿ѹۿձƵwww һ˿Ƶwww߸嶯 </a>| <a href="http://5tww.com" target="_blank">jŮjڲվ</a>| <a href="http://kmp77.com" target="_blank">ҹ³˿ƬAV</a>| <a href="http://gysysz.com" target="_blank">޳a˲߹ۿ</a>| <a href="http://27simnjingmiguan.com" target="_blank">뾫Ʒþþ</a>| <a href="http://shenghe228.com" target="_blank">ëƬƵ</a>| <a href="http://wx-jn.com" target="_blank">޾Ʒmv߹ۿ</a>| <a href="http://15nw.com" target="_blank">a߹ۿַȫ</a>| <a href="http://www282pp.com" target="_blank">Ұһ</a>| <a href="http://gzmandala.com" target="_blank">ղƷBD߹ۿ</a>| <a href="http://zanyoo.com" target="_blank">ɫƵվ</a>| <a href="http://xiaojiejieav.com" target="_blank">Ʒ</a>| <a href="http://zz1965.com" target="_blank">һɪ</a>| <a href="http://963315.com" target="_blank">ĻmvѸ </a>| <a href="http://pyjxyey.com" target="_blank">޹av뾫Ʒ</a>| <a href="http://jaubus.com" target="_blank">츾һ </a>| <a href="http://hqshimo.com" target="_blank">ѻɫַվ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>