??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲黄色免费网站,亚洲人成色77777,亚洲AV综合色区无码二区偷拍http://www.tkk7.com/tw-ddm/<div id="ddm_subTitle"> <h2 class="catchline"> 哪怕没有办法一定有说法,<br/> q没有鸽子一定有乌鸦,<br/> 固执无罪&nbsp;梦想有h,<br/> 让他们惊? </h2> </div>zh-cnSun, 11 May 2025 08:11:56 GMTSun, 11 May 2025 08:11:56 GMT60Nifi同步数据的几U方?/title><link>http://www.tkk7.com/tw-ddm/articles/433715.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 09:27:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433715.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433715.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433715.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433715.html</trackback:ping><description><![CDATA[<span style="font-family: Arial; font-size: 10pt;">l常会遇到将Table从一个DB同步到另一个DB的需求,不同需求下Q可使用的处理方式会有不同:</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">1. 使用特定的Processor</span><br /><span style="font-family: Arial; font-size: 10pt;">比如Upsert或自行开发的Processor</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">2. 在Nifi程中自行构建SQL及其l定参数</span><br /><span style="font-family: Arial; font-size: 10pt;">比如借用ConvertJsonToSQL的二ơ加?/span><br /><br /><span style="font-family: Arial; font-size: 10pt;">3. RouteOnAttribute的分?/span><br /><span style="font-family: Arial; font-size: 10pt;">最多能分出DeleteQUpdate是无能ؓ力的Q而且q要考量资料序</span><br /><br /><span style="font-family: Arial; font-size: 10pt;">4. 仅新?+ DB层面的二ơ处理。这个其实是可以适用于所有情况,Nifi程贼简单,但DB上的东西多?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 在收方加多一张tmp表,l构与正式表一_但就是没有key。Nifi同步资料指到tmp?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 在tmp表上加多TriggerQ在q里面CodingL制Insert、Update和Delete. Trigger里面除了不能Truncate TableQ其它啥都能?/span><br /><span style="font-family: Arial; font-size: 10pt;">. 加多一个Job或EventQ定时去清tmp表,防止它爆?/span><br /><img src ="http://www.tkk7.com/tw-ddm/aggbug/433715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 17:27 <a href="http://www.tkk7.com/tw-ddm/articles/433715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RouteOnAttribute的用?/title><link>http://www.tkk7.com/tw-ddm/articles/433714.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 08:55:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433714.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433714.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433714.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433714.html</trackback:ping><description><![CDATA[<div style="display: inline-block;"><h5><span style="font-family: Arial; background-color: #ffffff; font-size: 10pt;">RouteOnAttribute</span></h5><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">    q个lg的是用途是ҎAttribute的D行Route分流Q从输入输出的角度来看,它可以把一个Input分成多个Output出来Q它的分支不同于E序中的Switch语法Q而等效于多条的IF语句Q也是说若Output的条件全部都W合Q它是可以把1个输出Copy到多个输出的Q所以它也可以用于条件复制的应用上?br />    关于资料落地的文章里我有提到qRoute的用范_它应该用在能够以Key做分支条件的场景Q也是说相同的Key一定会走固定的Output出来Q这h不会出现资料乱序的状c下面有两个CZQ第一个是典型的分支用法,W二个比较有意思,它的作用相当于Oracle中的Decode语法<br /><br /></span><h5><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">CZ1</span></h5></div><div><span style="font-size: 13.3333px;">    使用Route做流E的分支Q根据一个叫SO的栏位是否ؓI决定走不同的流E?左右的UpdateAttribute可以把它们想象成两个完全不同的处理流E来?<br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route1.png" width="600" height="216" alt="" /><br /><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    RouteOnAttribute</strong>Q?/span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">作用是根据Attribute的Bool值来军_是否q入该分?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/RouteOnAttributeProcessor1.png" width="600" height="443" alt="" /><br /></span><ul style="font-size: 12px; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>HasSO / NonSO</em></font><font face="Trebuchet MS, 宋体">Q这是我自行定义的两个Route名称 (不是属性名U?QValue是一个表辑ּQ若它的?trueQ则Output会进该Route</font></span></li><ul><li style="font-family: "Trebuchet MS", 宋体;"><span style="font-size: 8pt;">Nifi的表辑ּ语法不怎么好写Q官方的文档上有些东西ƈ不支?(不确定是不是Nifi版本~故)。这里还是可以看得出来就只是判断一个叫SO的Attribute的值是否ؓI?--- q记得有些Processor里面q有?Null Value Representation"的属性吧Q若是那里配?null"那这里也要与之匹配?/span></li></ul><li style="font-family: "Trebuchet MS", 宋体;"><span style="font-size: 8pt;">l过该Processor处理后,SO为空的会走右端逻辑Q而不为空的则会走左段逻辑Q同时它会加多一个叫"RouteOnAttribute.Route"的AttributeQ内容即为Route名称<br /></span></li></ul><span style="font-size: 13.3333px;"><br /></span><h5><span style="font-size: 13.3333px;">CZ2Q?/span></h5><span style="font-size: 13.3333px;">    Ҏ多个栏位是否有?不ؓI?Q让它们能够q入不同的RouteQ后面再ҎRoute名称d态的取|它的特点是Nifi程q没有出现分?Connection上是勾了所有的Route)Q只是ؓ不同的数据设上了一个变量名U?br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route2.png" width="600" height="298" alt="" /><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    RouteOnAttribute</strong>Q?/span><span style="font-family: Arial; background-color: #ffffff; font-size: 10pt;">借用</span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">分支名称在后面搞事,q里相当于是l资料加上了一个变量名U?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/RouteOnAttributeProcessor2.png" width="600" height="442" alt="" /><br /></span><ul style="margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>MO / MODELFAMILY / UPN / USN</em></font><font face="Trebuchet MS, 宋体">Q这是定义的四个Route名称Q判断条仉很简单,只是不为空</font></span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">值得注意的是q?个条件ƈ非是互斥条gQ比如有一W资料它的MO、USN都不为空Q那么就会同时进入两个Routeq行输出Q所?span style="color: red;">OutputW数会是2</span></font></span></li><span style="font-size: 13.3333px; font-size: 13.3333px;"></span><li><font face="Trebuchet MS, 宋体"><span style="font-size: 10.6667px;">下面q是q入UPNq个Route后的资料上的Attribute: "RouteOnAttribute.Route"<br /><br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/Route3.png" width="600" height="405" alt="" /></span></font></li></ul></ul><span style="font-size: 13.3333px;"><br /><br /></span><span style="font-family: Arial; font-style: italic; background-color: #ffffff; font-size: 10pt;"><strong>    UpdateAttribute</strong>Q?/span><span style="background-color: #ffffff; font-size: 10pt; font-family: Arial;">比较_ֽ的用?/span><br /><span style="font-size: 13.3333px;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor4.png" width="600" height="442" alt="" /><br /></span><ul style="font-size: 12px; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><font face="Comic Sans MS"><em>mqttTopic</em></font><font face="Trebuchet MS, 宋体">Q这是定义的一个MQTT的Topic变量Q它的内Ҏ可变动的Q会ҎRoute的不同生不同的l果</font></span></li><ul><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">MO/MODELFAMILY/UPN/USNq?个条件有M不ؓI,则会要求推送TopicQ?xxxx/【Type?【Value?yyyy</font></span></li><span style="font-size: 13.3333px;"></span><ul><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">【Type? ?mo"?modelfamily"?upn"?usn"q四个g一</font></span></li><span style="font-size: 13.3333px;"></span><li><span style="font-size: 8pt;"><font face="Trebuchet MS, 宋体">【Value? 为MO/MODELFAMILY/UPN/USNq四个Attribute的取?(?${MO} / ${MODELFAMILY} / ${UPN} / ${USN} 的?Q这里用了双层<span style="color: red;">${${"RouteOnAttribute.Route"}}</span>的取值方法来实现动态的取用变量?/font></span></li></ul></ul></ul><span style="font-size: 13.3333px;"><br /><br /><br /></span></div><img src ="http://www.tkk7.com/tw-ddm/aggbug/433714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 16:55 <a href="http://www.tkk7.com/tw-ddm/articles/433714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Kafka资料落地至MariaDB Q带Key的新增、修改和删除Q?/title><link>http://www.tkk7.com/tw-ddm/articles/433713.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Thu, 11 Apr 2019 07:40:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/433713.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/433713.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/433713.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/433713.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/433713.html</trackback:ping><description><![CDATA[<h5>需求:</h5><span style="font-family: Arial; font-size: 10pt;">    比较前一文章来_仅加多Delete的行为。例如我仅需要Status=1的资料,所以对于资料落地来Ԍ最合适的莫过于下面这PTable也可以自动保持最量的有效资?br /></span><span style="font-family: Arial; font-size: 10pt;">    1. 新资料Status=0Q执行Insert;<br /></span><span style="font-family: Arial; font-size: 10pt;">    2. 资料修改Status=0Q执行Update;<br /></span><span style="font-family: Arial; font-size: 10pt;">    3. 资料状态变更Status=1Q执行Delete;<br /></span><span style="font-family: Arial; font-size: 10pt;">    4. 若资料状态重新变更ؓ0Q则又会执行Insert;</span><br /><br /><h5><span style="font-family: Arial; font-size: 10pt;">思\Q?/span></h5><span style="font-family: Arial; font-size: 10pt;">  </span><span style="font-family: Arial; font-size: 10pt;">  按理来说Q只要通过分支Route可以将Insert/Update与Delete作业分成两条Nifi支流(看网上确实有很多q么整法?Q但是用Route有一个问题处理不了,那就是资料顺序的正确性你是无法保证的。对于小数据量的场景来说Q每WKey的多ơ操作间隔可能会比较长,所以它不会有什么问题,但大数据量的情况下,两同相同Key值的资料走Route后被处理的顺序؜乱就会造成最l资料结果的异常(比如应该是先Insert再DeleteQ结果却是发现资料还w在Table?。而大数据量在使用Kafka做ؓ数据源时׃可避免会出现Q即使业务数据量实不大Q但对于U篏了好几天的数据再q行接收Ӟ那一瞬间的数据量也会是很大的?br /></span><span style="font-size: 10pt; font-family: Arial;">   所以我们能做的是动态决定执行Delete和Insert?/span><br /><br /><h5>解决ҎQ?/h5><span style="font-family: Arial; font-size: 10pt;">虽然?a href="http://www.tkk7.com/tw-ddm/articles/433711.html">前一?/a>来说差异不大Q但Nifi程上却有很大不同,下面会详l描qCؓ什么要q样?br /><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/ReceiveData_Delete.png" alt="" /><br /><br /><br /></span><h5><span style="font-family: Arial; font-size: 10pt;">Processor及其讑֮Q?/span></h5><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ConsumeKafkaRecord、SplitJson、Connection、EvaluateJsonPath</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">与前一章的一P只是不同数据下解析的属性有所不同Q这里不再详q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><br /></span><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    UpdateAttribute</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">作用是从Kafka中Consume?以Record的Ş态)Q这里用Record是因为源数据是以Record的方式存上去?(Avro Schema)<br /><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor2.png" width="600" height="442" alt="" /></span></blockquote></span><ul style="font-size: 12px; font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li><span style="font-size: 8pt;"><em>SQL1</em>Q这才是q次花招的关键,在这里根据STATUS自行构徏SQL语句</span></li><ul><li><span style="font-size: 8pt;"><em>Status=0</em>Q构建的是Delete From xxx Where Key1=? and Key2=? q样的删除语?/span></li><li><span style="font-size: 8pt;"><em>Status!=0</em>Q构建的是Replace Into xxx (Key1,Key2,col3,col4) Values ( ?, ?, ?, ?) q样的Insert or Update语句</span></li></ul><li>l此Processor处理后,资料落地所需的SQL构建好了,后箋的问题就是如何去l定参数和执?/li></ul><br /><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ReplaceText</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">作用是对FlowFileq行文本替换Q这里用它来直接生我所需的JSON内容</span><br /><span style="font-family: Arial; font-size: 10pt;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: Arial; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/ReplaceTextProcessor2.png" width="600" height="442" alt="" /></span></blockquote></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>Search Value</em>Q这里用的是Default?/span>(?s)(^.*$)Q作用就是把原先的整份文件全部换?/li><li style="font-size: 12px;"><em style="font-size: 8pt;">Replacement Value</em><span style="font-size: 8pt;">Q这里放的就是一个固定结构的JSONQ可以看到里面的属性值都是用的Attribute (它们的值来源于前面的EvaluateJsonPath从源JSON文g中的提取)</span></li><ul style="font-size: 12px;"></ul><li><span style="font-size: 10.6667px;">l心的朋友可以发现这里是与前一文章的最大不同,q里没有使用AttributeToJsonȝ接生JSON文gQ而用的是更加笨拙的方式</span></li><ul><li><span style="font-size: 10.6667px;">前面的文章有提过Q我们生的Attribute以及AttributeToJson所生成JSON中各属性的序问题Q结论是怎么搞它都不是我所惌到的序。但是ConvertJsonToSQLq个东东却很实在Q它确实实是按JSON中属性的序ȝ成的SQL以及参数名称(q记得参数名Usql.args.</span><span style="font-size: 10.6667px; color: red;">1</span><span style="font-size: 10.6667px;">.value中的q个序</span><span style="font-size: 10.6667px; color: red;">1</span><span style="font-size: 10.6667px;">?Q所以问题就来了Q?/span><br /></li><ul><li style="font-size: 12px;">SQL׃必须要有Delete和ReplaceQ所以它们的参数个数一定是不同的,而Delete压的参数又是我们的KeyQ所以就必须要保证ConvertJsonToSQL生成属性的序Q这h们才能够保证我们的两个Key一定会是sql.args.1和sql.args.2</li></ul><span style="font-family: Arial; font-size: 10pt;"></span><ul><li style="font-size: 12px;">换句话说Q如果AttributesToJson若是能够保证JSON属性顺序的话,那就不用q么费劲</li></ul></ul></ul><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    ConvertJsonToSQL</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; font-size: 13.3333px; background-color: #ffffff;">与前文一P以Insert的方式生成SQL和绑定参数即?/span><br /><span style="font-family: Arial; font-size: 10pt;"><br /></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    UpdateAttribute</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="background-color: #ffffff;"><font face="Trebuchet MS, 宋体"><span style="font-size: 10pt;">l于用到了它的Delete功能Q作用是清除掉多余的SQLl定参数</span></font><br /><blockquote style="font-family: "Trebuchet MS", 宋体; font-size: 10pt; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/UpdateAttributeProcessor3.png" width="600" height="441" alt="" /><br /></span></blockquote></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>Delete Attributes Expression</em>Q这里我ҎDelete的条?STATUS=0)d除多余的SQLl定参数</span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;">q里的写法比较死Q我Hard-code删除掉大?的其它所有参?" </span><span style="font-size: 8pt; color: red;">*</span><span style="font-size: 8pt;"> "</span><span style="font-size: 8pt;">是一个通配W," </span><span style="font-size: 8pt; color: red;">|</span><span style="font-size: 8pt;"> "是一个多条g的间隔符)Q感觉上q有更好的写?/span></li></ul><li style="font-size: 12px;"><span style="font-size: 8pt;">x我们可以保证绑定参数的数量与SQL语法参数个数一?(不一致它ȝ你看)</span></li><ul style="font-size: 12px;"></ul></ul><span style="background-color: #ffffff;"></span><span style="background-color: #ffffff;"><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;"><br /></span></span><em style="font-family: "Comic Sans MS"; font-size: 13.3333px; background-color: #ffffff;"><strong>    PutSQL</strong></em><span style="font-family: "Trebuchet MS", 宋体; font-style: italic; background-color: #ffffff; font-size: 10pt;">Q?/span><span style="font-family: "Trebuchet MS", 宋体; background-color: #ffffff; font-size: 10pt;">q里仍然是执行SQLQ这里用配|参数的形式让它执行我们的SQL</span><br /><span style="font-family: Arial; font-size: 10pt;"><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><span style="font-family: Arial; font-size: 10pt;"><img src="http://www.tkk7.com/images/blogjava_net/tw-ddm/PutSQLProcessor2.png" width="600" height="440" alt="" /></span></blockquote></span><span style="font-family: Arial; font-size: 10pt;"><br /></span><ul style="font-family: "Trebuchet MS", 宋体; margin-left: 1em; background-color: #ffffff;"><li style="font-size: 12px;"><span style="font-size: 8pt;"><em>SQL Statement</em>Q前面用UpdateAttribute产生的SQL1参数Q它会根据STATUS=0d断是使用DELETEq是REPLACE语法</span></li><ul><li style="font-size: 12px;"><span style="font-size: 8pt;">q个属性压上后Q无论SQL1是不是ؓI,q个lg都不会再ȝFlowFile的内?I属性时是把FlowFile的内容当成SQLL行的)</span></li></ul></ul><img src ="http://www.tkk7.com/tw-ddm/aggbug/433713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2019-04-11 15:40 <a href="http://www.tkk7.com/tw-ddm/articles/433713.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Kafka资料落地至MariaDB Q带Key的新增、修改)http://www.tkk7.com/tw-ddm/articles/433711.html大大?/dc:creator>大大?/author>Thu, 11 Apr 2019 06:14:00 GMThttp://www.tkk7.com/tw-ddm/articles/433711.htmlhttp://www.tkk7.com/tw-ddm/comments/433711.htmlhttp://www.tkk7.com/tw-ddm/articles/433711.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/433711.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/433711.html需求:    接收Kafka资料Q资料具有Key?多列)Q有新增、修改但无删除,需要同步落地至MariaDB
解决Ҏ(仅新增、修?Q?/h5>    q个场景是最常见的,资料不会有被删除的状态,所有的更新只有Insert Or Updateq两U状态,先上实例的图 (两边的LogMessage是ؓ了接收FailQ有感叹h避免一起开启的时候它也被开?---q样failure的讯息就不会再卡在Connection中了)


思\Q?/span>
    因ؓ记录只有新增和修改两U状态,理论上说q两U的SQL非常接近Q所以可以做以下考量
    1. Processor层面是否支援Update Or Insert
      > 查网上讯息有个叫UpsertQ不q在Nifi中查找,只有一个支援Mongo的组件具有这个功?/span>
    2. DB层面是否支援
      > Maria DB有个 "REPLACE INTO" 的语法是可以支持Insert Or UpdateQ虽然简单看了下介绍说是会依主键或唯一索引d做定位,如果定位到已l存在则先做删除再进行新增(伪UpdateQ,但确实可以达成我们的目的Q不是吗Q?/span>

Processor及其讑֮Q?/span>
    ConsumeKafkaRecordQ作用是从Kafka中Consume?以Record的Ş态)Q这里用Record是因为源数据是以Record的方式存上去?(Avro Schema)
  • Kafka BrokersQKafka的Broker列表Q多个Broker以逗号分隔Q类似www.broker1.com:9193,www.broker2.com:9193q样的Ş式配|?/font>
  • Topic NameQ需要Consume的Kafka Topic名称
  • Record Reader/WriterQ关于Record所需要设定的Reader和WriterQ要先行在Configure中设定,当然也要讑֮好Schema  
  • Group IDQConsumer所要设定的IDQ这个的讑֮要依Kafka的配|来Q现在我们一般就只有单个的PartitionQ所以会要求每个Processor都设定有不同
  • Offset ResetQ需要设定ؓ"earliest"Q这样就会依GroupID没有收过的资料来q行收取Q否则就只会收新推上ȝ资料。第一ơ玩的兄弟经常坑在GroupID和Offset Resetq两上Q若是收不到资料则有  可能是GroupID没有换成新的(旧的已经收过一ơ就不会重新再收)Q或者是Offset Reset = latest又没有新资料推上去~~~
  • Max Poll Records和SCHEDULING中的Run ScheduleQ需要根据实际接收的速度来进行调整。经q观察发现Consume的速度快Q但整个Nifi Flow的速度会卡在其它需要做解析或读写DB的Processor?(通常解析JSON会是前面的关?Q所以Q由Consumer的高速读取就会造成整个Nifi程在后D被卡住。造成q个的主要原因其实就在于kafka处理的高速上Q所以当有新换GroupID或新程ӞKafka上积累的量资料׃在一瞬间被接收下来,然后是各种U?(其实U了也没事,它会自动向上推,让前一个Processor停止处理)?br />
    • 若是常态下的资料推送量已l超q了你的Nifi处理速度Q那么就要考量使用多个U程处理或者是从源头的Kafka上就把资料分割开?nbsp; 
    • SCHEDULING的Cocurrent TasksQ这个Default=1Q就是当前Processor需要开h的线E数。但是这个设|需要当心,你需要仔l考量q你的资料流是否允许乱序 (多线E时当然不可能还能保证资料处理的序)Q所以它是仅适用于不Care资料处理序的场景,例如每笔Key只会有一W资料,而且哪笔资料先收后收无所?/span>

    SplitJsonQ作用就只是单的把一个JSON数组切开成单个的JSON。Consume出来的会是个数组Q这跟你存放q去的单W讯息是不是数组没什么关pR?/span>

    ConnectionQ就是Processor中的那根带箭头的q线Q它的作用是q接不同的Processorq且它还h~存池的的一个用途,除了把数据从A导流向B外,q可以将B暂时处理不动的资料存攑֜自带的缓存池中,若是~存池达C限,则Nifi会自动让A暂停处理直至B~过劲~~~
  • Back Pressure Object Threshold / Back Pressure Data Size ThresholdQ最大缓存的消息W数 / 最大缓存消息的体积Q两者Q一过׃让上游Processor处理暂停
  • Available PrioritizersQ出入缓存池的顺序控ӞDefault是空Q通常来说都应该要设成FIFO先进先出的方?/span>
    • 不设定这个经怼造成Nifi资料处理丢失的假象,A1,A2,A3,A4Q最后看到的不是A4而是A3Q会让h以ؓA4被玩掉了Q其实只是A4被先处理Q而A3变成了最后一W状态。而且q种错误很难被发?!


    EvaluateJsonPath1Q这个元件的作用是解析JSONQ它也只能简单的解析Q想在Value中对取出来的值做一些处理好象是不允许的....
  • DestinationQ表C析出来的内容是成为AttributeQ还是直接替换Flow File内容Q这里设定是做ؓ属性,所以Processor处理后就可以在Flow File上看到多定义的那些属性以及它们的?/span>
  • Return TypeQ返回值的cdQ这U简单从JSON中取值的可以使用Auto-detect卛_
  • Path Not Found BehaviorQ是说如果设定需要解析的JSON路径不存在时的处理行?/span>
  • Null Value RepresentationQ这个对于Null值的处理Q?"empty string"会将null设ؓI字W串(MO=)Q另外一?the string 'null'"则是会将null设ؓ"null"q样的字W串 (MO="null")
  • MO/MODELFAMILY/....Q这些是我手工添加的属性名Uͼ需要根据JSON长样来设Q对应Value讑֮?.MO则是表示MO的值来源于JSONW一层的"MO"节点?/span>
    • 需要注意的一Ҏ属性名U貌似是会区分大写的,所以可以看到我全部使用的大?/span>
  • 截图是运行时态的ProcssorQ停止运行时PROPERTIES上会有一?+ P点它卛_以新增自q属?br />
    • 有一Ҏ较奇怪的地方Q就是通过+L护进ȝ多个属性,它们的排列顺序却不是你手工新增的序Q这点引发另外一处的一个疑问,会在下面?br />
    EvaluateJsonPath2Q当然也是要从JSON中解析,只不q我是要把整个JSON的内定w保留下来Q由于它们要求的讑֮不同Q所以被q要撕成两个元g来做
  • DestinationQ这个设定仍然是属?/span>
  • Return TypeQjsonQ第一个解析元件虽然可以随意设|,但把q两U合q成一个元件ƈ使用Auto时就会报错,所以看hW一U简单属性实际上只支持Scalar?..
  • JSONDATAQ我定义的一个属性名Uͼ注意Value中设定的"@"W号Q它表示整䆾FlowFile的内?前面已经转成一个JSON)
  • q个JSONDATA是因为我的需求,因ؓKafka上的资料来源于其它系l,而我其实只需要其中的量几个栏位 (前一个EvaluateJsonPath解析的那?Qؓ了备查数据上的其它栏位以及在后箋使用Q所以才要把整䆾JSON都保留到DB中去 (说得q么高端Q实际的原因却是他们的JSON属性是用程序硬拼字串拼出来的,有的东西实在是在Nifi中搞不出?.....)

    UpdateAttributeQ元件用途是对FlowFile的Attrubuteq行修改Q这里是拿来对解析出来的D行再加工以及d新属?/span>
  • Delete Attributes ExpressionQ这个属性如果有讄pCProcessor为Delete属性的状态,会忽略你新加的那些属性处理,只专心做好一件事"删除W合条g的属?
  • PROVIDERQ这是一个新的属性,它ƈ没有包含在JSON中,是ؓ表示数据来源而新加的
  • SOQ这个就是前?div style="display: inline-block;">EvaluateJsonPath1解析出来的某个|那个元g无法直接加工Q所以放在这里做的二ơ加工,L前导0

    AttributesToJsonQ作用是一堆Attribute转换为JsonQ当然就只能是那U简单结构的JsonQ这里用它是ؓ了配合后面一个Processor的?/span>
  • Attributes ListQ拿来生成JSON的属性列表,q里我其实把EvaluateJsonPath1、EvaluateJsonPath2和UpdateAttribute产生的属性都放上M (它们是我落地MariaDB的Table?
    • 不得不说的一个灰帔R憄l果Q那是生成的JSON属性顺序绝对不是你在List中写的属性顺序,我比较怀疑是在前面几个组件生成Attribute的顺序,但更让h遗憾的是它们的顺序也不会是你l护它们的顺序。这个结果会D我们在另外的Case 2中会到一个不可逾越的障~~~~
  • Attributes Regular ExpressionQ符合条件的正则表达?/span>
  • DestinationQ?q个属性在 
    EvaluateJsonPath?/div>
    有Q?它可以让l果成ؓ一个新的属性还是直接替换FlowFile的内容, Default是直接换掉FlowFile的内宏V?/div>

    ConvertJsonToSQLQ作用是ҎJSON内容转换成SQL语句以及语句所要的参数Q经q这一兛_FlowFile的内容就变成SQL语句Q然后Attribute中多Z些参?/span>

  • JDBC Connection PoolQConfigrue中指定的MariaDBq接字符Ԍ那里直接有指定Schema
  • Statement TypeQ?/em>q个有INSERT、UPDATE、DELETEq?个选项Q若是Mongo的那个组件就会看到有UPSERT(Update or Insert)Q其它各cȝ都木有~~~Q这里我使用的是INSERT选项Q后面通过玩的一点小花招把它再折腾ؓREPLACE INTO
  • Update KeysQ?q个属性可以不填,它是For Update时用的
    ?/div>
  • SQL Parameter Attribute PrefixQ?default = sqlQ它其实影响到组件处理后生成的SQL语句参数叫什么,设ؓsqlQ最后就会看到生成出?div style="display: inline-block;">。如下图是处理后的Attribute样式Q它会生sql.args.X.type和sql.args.X.valueQ这一l合h对应于SQL中第一?参数的类型及|”sql"是我们q里讄的前~名称 (充分考虑到大家会惌搞事)

    ReplaceTextQ作用是文本替换Q这里就是我们处理Update Or Insert的关键,直接把SQL语句换掉?/span>
  • Search ValueQ在FlowFile中查扄字符Ԍ它支持正?/span>
  • Replacement ValueQ?/em>替换的|q里是单的把Insert Into (x1,x2,x3) values (?,?,?)处理为Replace Into (x1,x2,x3) values (?,?,?)而已QReplace Or Insert的行ZlDBd

    PutSQLQ作用是在DB上执行一DSQL语句
  • JDBC Connection PoolQ前面ConvertJsonToSQL转换SQL时就有用q,指定数据库的q接
  • SQL StatementQ?/em>需执行的SQLQؓI时表示使用前面传递过来的FlowFile的内?已经是一个SQL语句)


ȝQ?/h5>
    q是一个带有Key?多个Key?的无删除行ؓ的资料接Ӟ所以可以利用AttributeToJSONd提取出来的有用属性重新生成JSON文gQƈ直接利用ConvertJsonToSQL转换为Insert语句及对应的l定参数Q这里借用了MariaDB提供的Replace Into机制去自动用表上的Key键去做Update更新Q所以整个Nifi Flowq是比较单。在后箋文章中会讲到带Delete行ؓ的资料接收方法以及无Key更新的解x?/span>


]]>
Oracle资料推送MQTThttp://www.tkk7.com/tw-ddm/articles/433709.html大大?/dc:creator>大大?/author>Wed, 10 Apr 2019 07:25:00 GMThttp://www.tkk7.com/tw-ddm/articles/433709.htmlhttp://www.tkk7.com/tw-ddm/comments/433709.htmlhttp://www.tkk7.com/tw-ddm/articles/433709.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/433709.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/433709.html需?/span>
资料从Oracle推至MQTTQ资料结果用JSON格式
场景1Q直接推?/span>
场景2Q仅当资料有变更时才推?/span>

解决Ҏ
QueryDatabaseTable --> ConvertAvroToJSON --> PublishMQTT


Processor及其讑֮Q?/span>
QueryDatabaseTableQ?/span>作用是从DB中捞取资料,可以惌Nifi把它转成一个Select语句在执?/span>


  • Database Connection Pooling ServiceQ在Configure中设定的数据库连接,可以在Processor Group中被q
  • Database TypeQ这个设定的是Oracle。其实它与数据库q接讑֮有点重叠Q那边已l有指定是哪一U类型的DBQ这里需要再指定Q我想会不会是利用它来生成不同的Select查询语法?
  • Table NameQ表名,我这里用的是View名称QView其实已l对Table做出一些限定,可以挑选列及设定查询条?/span>
  • Maximum-value ColumnsQ这个属性很重要Q如果不讑֮则Nifi在查询的时候会捞取所有的资料Q如果有讑֮某个列,则Nifi仅会捞取“?#8221;资料
    • 例如图上讑֮“BATCHID”q个列。第一ơNifi启动时捞取资料中最大BATCHID = 10Q则下一ơNifi再次启动时就只会捞取BATCHID>10的资料,q且会自动记录下已经捞过的最大?/span>
    • 最大g存在下面q里QProcessor上右键选择“View State”


    • 下图可以看到当前最新的|?#8220;Clear State”则可以将保留值清I(Nifi下次启动时就会捞取所有资料)

  • 对于仅需要简单拉取资料的场景1来说Q?#8220;Maximum-value Columns”|空卛_Q而对于仅在资料有更新时才要拉取的场景2来说Q则需要设定ƈ且在View中做Z些调整才可以达成
    • 当有资料更新Ӟ则被更新资料的BatchID会是更新的|所以只要在View中虚拟BatchID?= Max(BatchID)Q就可以达成有资料更新才要拉取的效果
ConvertAvroToJSONQ将Avrocd资料转换为JSONQ这个可以不用改讑֮

PublishMQTTQ将资料Publish到MQTT指定Topic
  • Broker URIQ?/span>MQTT的Broker地址
  • Client IDQ?/span>发布MQTT的Client端IDQ注意不要多个Processor使用相同的Client IDQ这样ProcessorҎ被卡死)
  • TopicQ?/span>发布至MQTT的Topic名称
  • Retain MessageQ?/span>MQTT的遗a属性,x否保留推送的消息Q若设ؓfalseQ则仅有当前q上MQTT的客L才能收到q笔消息Q?/span>



]]>
ADO提交多筆SQL的問?/title><link>http://www.tkk7.com/tw-ddm/articles/255166.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Tue, 17 Feb 2009 10:50:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/255166.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/255166.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/255166.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/255166.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/255166.html</trackback:ping><description><![CDATA[ <p> <font face="Georgia" size="2">使用ADO時經帔R會遇到要利用事務Ҏ提交SQL的情況,如果使用不當的提交方式會出現預料外的問題Q現在先看下面的CZ代碼Q?br /></font> <br /> </p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"> <span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">Private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Sub</span><span style="COLOR: #000000"> cmdRun_Click()<br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">On</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Error</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">GoTo</span><span style="COLOR: #000000"> ErrHandle<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Dim</span><span style="COLOR: #000000"> con </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> Connection<br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Dim</span><span style="COLOR: #000000"> strSQL </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">String</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">    strSQL </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">W一{SQL1</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    strSQL </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> strSQL </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Insert Into tb1 Values (...)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> vbNewLine<br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">W二{SQL2</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    strSQL </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> strSQL </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Update tb1 Set C=1 Where ...</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> vbNewLine<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">...</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">WN{SQLn</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    strSQL </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> strSQL </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Delete tb1 Where ...</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> vbNewLine<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Set</span><span style="COLOR: #000000"> con </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> getCon()  </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">獲取/打開DB連線</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">準備事務</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    con.BeginTrans<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">一批一起執?/span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    con.Execute strSQL<br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">提交事務</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    con.CommitTrans<br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">ExitHandle:<br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">If</span><span style="COLOR: #000000"> con.State </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Then</span><span style="COLOR: #000000"> con.Close<br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Set</span><span style="COLOR: #000000"> con </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Nothing</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Exit</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Function</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">ErrHandle:<br /></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000">    con.RollbackTrans<br /></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">GoTo</span><span style="COLOR: #000000"> ExitHandle<br /><span style="COLOR: #008080">27</span><font style="BACKGROUND-COLOR: #eeeeee"> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff"><font color="#0000ff">MsgBox</font></span><span style="COLOR: #000000"> Err.Description<br /></span></font></span><span style="COLOR: #008080">28</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">End Sub</span></div> <br /> <font face="Georgia" size="2">   上面這段E式<strong>利用換行W?分號也可)來將多條SQL合成一個字W串Q最後在事務中執行一?/strong>OKQ既潔又漂亮的x?br />   看似OKQ但實際L埋下了禍端。從事務的機制來看,在事務中提交的SQL應該是一h?失敗的,而且這裏也有利用異常捕獲制來實現RollBackQ那麽在使用時到底是會出現什麽情況呢?<br />   (0) SQL1,SQL2,...SQLn其中有語句含有非埯時的語法錯誤Q比如說嵌套語句掉一個右括號{;<br />      <strong><font color="#0000ff">OK</font></strong>。這種情況下,可以發現埯i果如預期,SQL1 -> SQLn都不會被埯Q且會提C錯誤訊息?br />   (1) SQL1,SQL2,...SQLn都執行成功;<br />      <font color="#0000ff"><strong>OK</strong></font>。這種情況下,可以發現埯i果如預期,SQL1 -> SQLn都會被執行,可以正確提交事務?br />   (2) SQL1,SQL2,...SQLn其中有語句會埯失敗Q?br />      (2.1) SQL1可以埯Q而SQL2會發生執行時期錯?比如UPDATE上去Ƅ位過寬度)Q?br />         <strong><font color="#ff0000">NO</font></strong>。Execute埯成功Q查詢結果會發現SQL1的結果有提交Q而SQL2以及之後的SQL都沒有執行?br />      (2.2) SQL1會發生執行時期錯?比如UPDATE上去Ƅ位過寬度)Q而SQL2及其後的SQL可以被執行;<br />         <font color="#0000ff"><strong>OK</strong></font>。這種情況下,可以發現有提C錯誤訊息,事務會被RollBackQSQL1 -> SQLn都不會被埯?br /><br />   通過上面的幾E情況可以得到結論,如果是以一整個字?中間用換行或分號分隔)來提交多{SQL命o時,在所有SQL語法檢查OK後,埯的成功與否取決於W?{SQL的執行狀態,因此是?strong>如果W一{SQL埯OKQ那麽該事務׃定會被Commit</strong>?br /><br />   所以說Q在使用事務提交多筆SQL時不能用上面的提交方式Q而必須逐筆的提交才行?br /><br /></font> <img src ="http://www.tkk7.com/tw-ddm/aggbug/255166.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2009-02-17 18:50 <a href="http://www.tkk7.com/tw-ddm/articles/255166.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VBE式分工及內部架?/title><link>http://www.tkk7.com/tw-ddm/articles/255162.html</link><dc:creator>大大?/dc:creator><author>大大?/author><pubDate>Tue, 17 Feb 2009 09:52:00 GMT</pubDate><guid>http://www.tkk7.com/tw-ddm/articles/255162.html</guid><wfw:comment>http://www.tkk7.com/tw-ddm/comments/255162.html</wfw:comment><comments>http://www.tkk7.com/tw-ddm/articles/255162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/tw-ddm/comments/commentRss/255162.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/tw-ddm/services/trackbacks/255162.html</trackback:ping><description><![CDATA[ <br /> <font face="Georgia" size="2">VBE式的結構比較自由,通常做法是新徏一個工E,然後建幾個FORM畫面並在其中放上代碼OKQ但是當一個工E的i構略顯複雜的時候就會造成整個程式結構上的沉重感Q修改及d功能時會造成力不從心的感覺,如果能夠E持一個比較簡潔的架構Q程式就會在可讀性及靈活性上得到極大的提高,下面如何定並E持這樣的架構做一個簡單地解?br /><br />1. 利用不同型的工E文件來實現分割Q?br />   做過VB的都應該知道Q常用的工程文g有FORMQMODULESQCLASS以及USERCONTROLS這四E,應該如何M用呢Q?br />   (1) Forms(H體)<br />      Form是最常見的文Ӟ利用它可以用來設a功能畫面。因此在劃分上應該將全部與實際功能相關的CODE都放在這裏?br />   (2) Modules(模組)<br />      這個是純a的代塊文gQ由於它本n的PUBLICҎ,因此應該是放|公用函式。這裏所說的“公用函式”並不是說裏面放的都是一些PUBLIC的FUN/SUBQ而是說從功能上來是與整個Project盔R的處理,比如說DB連線Q讀寫配|檔Q寫LOG{。而且裏面的FUN/SUB應該是PRIVTE與PUBLIC怺的一個結?Private應該是對多個Public的一個實現上的抽??br />   (3) Class(?<br />      Class因為可以被單獨的NEWQ因此它承擔的角色應該是一個單獨流E的抽象Q例如將讀寫EXCEL/發MAILa計成一個類?br />   (4) UserControls(用戶控g)<br />      這個東東我的理解是Class的擴充,畉要利用到現成控g進行擴充以及事g響應時就用它好了?br /><br />2.  工程內部分工Q?br />   (1) 要養成從Module.Main來做工程入口/出口的習慣,避免直接某個Forma為啟動H體和Q意地方的End?br />      用Module.Main做工E入口可以在固定的地方實珑օ口時的參數初始化及一及設定,避免出現aForm為啟動窗體後在添加對{功能塊時難g改及初始化的問題。例如需?先是Form1a為啟動畫面Q而後U需求要求設Form2為啟動畫面或是要整個EXE做成無須示畫面直接運行{?br />      在Module攄整個工E的出口(指結束時的處理Sub)Q能夠保證工E中引用的釋放?br />   (2) 全部的外部引用及定都攑֜Module中?br />      例如VBE式中經常會用到WindowsAPIQ那麽這些API的定應該是攑ֈModule之中(UserControls中用到除?<br /><br />3.  單獨模塊(指單一Form/Module/Class)內結構:<br />   (1) 一定要使用Option Explicit來實施D制定檢查,完全避免未定就使用變量這種情況的發生?br />   (2) Public的節制用,能夠定義為Private的方法就一定不要用PublicQ避免出珑ּ用؜亂及p困難?br />         <br />4.  Ҏ內結構:<br />   (1) 異常處理<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_171038" onclick="this.style.display='none'; Code_Closed_Text_171038.style.display='none'; Code_Open_Image_171038.style.display='inline'; Code_Open_Text_171038.style.display='inline';" height="16" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_171038" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_171038.style.display='none'; Code_Closed_Image_171038.style.display='inline'; Code_Closed_Text_171038.style.display='inline';" height="16" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_171038" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">Ҏ內結構示?/span><span id="Code_Open_Text_171038" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080"> 1</span> <span style="COLOR: #0000ff">Public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Function</span><span style="COLOR: #000000"> ReadTemplate(<strong>ByVal</strong> strTemplatePath </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">String</span><span style="COLOR: #000000">, <strong>ByRef</strong> strTemplateContent </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">String</span><span style="COLOR: #000000">) </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Boolean</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">On</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Error</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">GoTo</span><span style="COLOR: #000000"> ErrHandle<br /></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Dim</span><span style="COLOR: #000000"> lngFileHandle </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Integer</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Dim</span><span style="COLOR: #000000"> strLine </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">String</span><span style="COLOR: #000000">, strContent </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">String</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">    lngFileHandle </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">檢查模板文g是否存在</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">If</span><span style="COLOR: #000000"> Dir(strTemplatePath) </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Then</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">        Err.Raise </span><span style="COLOR: #000000">32001</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ReadTemplate</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">模板文g不存?/span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">End</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">If</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">'</span><span style="COLOR: #008000">載入模板文g內容</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    strContent </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    lngFileHandle </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> FreeFile()<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    Open strTemplatePath </span><span style="COLOR: #0000ff">For</span><span style="COLOR: #000000"> Input </span><span style="COLOR: #0000ff">As</span><span style="COLOR: #000000"> #lngFileHandle<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Do</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">While</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Not</span><span style="COLOR: #000000"> EOF(lngFileHandle)<br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">        Line Input #lngFileHandle, strLine<br /></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">        strContent </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> strContent </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> strLine </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> vbCrLf<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Loop</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">    strTemplateContent </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> strContent<br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">    ReadTemplate </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">True</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">ExitHandle:<br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">If</span><span style="COLOR: #000000"> lngFileHandle </span><span style="COLOR: #000000"><></span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Then</span><span style="COLOR: #000000"> Close #lngFileHandle<br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">Exit</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">Function</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">ErrHandle:<br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">    ReadTemplate </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">False</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000">    WriteErrLog gStrAppLogPath, TheMdlName, Err.Source, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">加載模板[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> strTemplatePath </span><span style="COLOR: #000000">&</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]失敗</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, Err.Number, Err.Description<br /></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">GoTo</span><span style="COLOR: #000000"> ExitHandle<br /></span><span style="COLOR: #008080">27</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">End Function</span></span></div>   可以看到上面的結構包含了異常處理Q在VBE式中最Ҏ出現的問就是異常的處理Q由於VB並不會象JAVA/NET那樣要求強制處理異常Q因此常帔R會忽略掉E式中的異常處理問題Q造成一旦出錯就會整個OVER的嚴重後果?br />   (2) 不要忽視FUN的返?br />      VB中Function/Sub都可以一樣直接?例如 Call Sub1/Function1...)Q在這樣隨意使用Function的同時,其返回值必定會被丟,極容易造成E式處理的邏輯分支被忽略?br />   (3) Sub/Function中參數要式聲明ByVal / ByRef 及參數Ş?br />      於單型的參怾,式聲明ByVal / ByRef 是表明該參數是否可以被修改,而聲明參數Ş態則可以從一定程度上避免VB自動轉型時的錯誤?br /></font> <img src ="http://www.tkk7.com/tw-ddm/aggbug/255162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/tw-ddm/" target="_blank">大大?/a> 2009-02-17 17:52 <a href="http://www.tkk7.com/tw-ddm/articles/255162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用TN5250NF下載檔案的自動化處理http://www.tkk7.com/tw-ddm/articles/254262.html大大?/dc:creator>大大?/author>Wed, 11 Feb 2009 07:51:00 GMThttp://www.tkk7.com/tw-ddm/articles/254262.htmlhttp://www.tkk7.com/tw-ddm/comments/254262.htmlhttp://www.tkk7.com/tw-ddm/articles/254262.html#Feedback1http://www.tkk7.com/tw-ddm/comments/commentRss/254262.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/254262.html 問題 

   珑֜有遇C個需求,是想直接利用TN5250來實?00端資料的下載Q?br />   1. 僅通過TN5250來完成,不要使用其他的元Ӟ
   2. 匯出資料格式為TXT檔案Q應該是要能夠放到局域網路上Q?br />   3. 匯出資料的動作需要做成排E方?例如每天匯出)Q?br />   4. 需求相當的急?br />
   使用TN5250NF可以直接?00端資料到PC端,匯出成TXT/XLS{格式的文g。匯出功能實際由TN4002PC來完成,該功能用v來非常方ѝ通過單a定連線/a定參數卛_實現資料的下載?br />
   如果不考慮到需要做成排E方式來自動進行Q則完全可以以h工方式來實現1-2?br />

思?/strong>

   要做直接利用E式的功能來實現自動化,首先應先弄清楚作業的方式是怎樣Q先來看看手工是怎樣下載的?br />   1. 點選TN5250上的菜單“傳送?> “從主電腦接收檔案”即可打開功能畫??)Q?br />
o_TN4002PC_01.GIF

   2. 需要配|參??)Q?br />o_TN4002PC_02.GIF
   >> 注意紅色框部分,輸出必須要設為“檔案”,而筆?0則表C將該檔案中全部資料都DOWNQ?gt;0則表C最大下載筆?如設?0則僅下載20{資?。其他部分根據需要自行配|?br />   >> 檔案名稱處定需要存攑֌出檔案的名稱及\徑,如果需要在E\路徑上匯出文檔則必須先將E絡路徑映射為本地磁?通過“我的電腦”上右鍵“連線E\碟”即可將一個網i\徑映成本地盤符)Q然後再使用Q否則會提示錯誤?br />
   3. 點選上圖的“開始接?R)”即可以開始?00下載資料到PCQ接收完成後會蟩息提C框(?)Q?br />o_TN4002PC_03.GIF

   另外Q還可以利用?上的“檔案”菜單來實現參敔R|的保存以及載入(Default是存?tt0檔案)?br />

   通過查看保存配置後生成的快捷方式Q可以發珑օ快捷方式內容實際??)Q?br />o_TN4002PC_04.GIF
   >> 紅色部分即為我保存的配置?-配置檔實際是一個INI文gQ可使用a事本打?br />
   因此Q用“TN4002PC.EXE /f=配置檔名E”這樣的Ş式即可從命o行實際對此功能的調用(先要參敔R配置好存在配|檔?。OKQ現在剩下就是要這個命令行能夠被放在“計劃Q務”中?br />
   通過手工測試可以發現有一些問還待解決:
   1. 在匯出完成後一定會有訊息框跛_(?)Q這個是相當於MSGBOX的窗口,它會整個程式阻塞在那裏Q如果不它消掉(回車或空?會造成多次處理出錯?br />   2. 配置參數時無法為匯出的TXT文檔指定一個動態名E,因為是要自動匯料放在一個固定\徑下Q所以每回匯出的文檔名稱都應該有所不同Q例如保存成帶日期格式?/font>


解決Ҏ

   因為是需要動態生成匯出文檔名以及消掉作業完成後的MSGBOXa息框,所以是必須要有E序來協助解決,E序使用VBS來實?先前有想到用BATQ但是無法解決MSGBOX的問??br />   E式的處理方法:
   1. 利用VBS來動態生成TTO配置文gQ只要每ơ修Ҏ保存的文件名E就好,這樣可以每ơ生成的TXT都有所不同?br />         解析保存配置的TTO檔案Q提取PC_FILENAMEa定Q在文g名後加上處理的日期和時間(路徑/文g型保持不變)Q最後再存成一個新的TTO配置檔?br />   2. 利用VBS來執行CMD命o(命o格式見圖4)Q完成對匯出功能的調用?br />         為TN4002PC指定新生成的TTO配置檔,實現功能的調用?br />   3. 在匯出完成後發送鍵盤指令關掉MSGBOX框?br />         因為VBS中看似沒法能夠直接獲取TN4002PC的窗口,所以是d處理--在程式處理過E中每間隔一D|間就L查生成的TXT檔案大小是否有變化,如果沒有變化則認定可能已匯出完成Q卡在MSGBOXH口QVBSE式pȀzMSGBOXH口並發送鍵盤的I格?br />   4. 在“計劃Q務”中a置VBSE序的調用?br />         利用a劃d_N可以完成VBSE序的調用,因為我這裏a計是要配|的TTO文g名做為參數傳iVBSE序。而XP下試過幾ơ都無法能在a劃d中直接將參數傳遞過去(2003d?Q所以就只有多做一只BAT(攄VBSE式的傳參調?攑֜a劃d中?br />
BAT批處理程?/strong>(藍色即為VBSE序Q紅色為保存的TTO配置?

start RunVBS.vbs C:\FGPPOLR.tto

VBSE序

VBSE序

排程埯完後(每次都會有FDF--Ƅ位定義和TXT--檔案內容兩個文件生成,多次RUN出文件名會不?:
o_RUNED.GIF


下載

      VBS文g



]]>
大資料量SQL性能優化之轉換思\http://www.tkk7.com/tw-ddm/articles/239935.html大大?/dc:creator>大大?/author>Tue, 11 Nov 2008 10:55:00 GMThttp://www.tkk7.com/tw-ddm/articles/239935.htmlhttp://www.tkk7.com/tw-ddm/comments/239935.htmlhttp://www.tkk7.com/tw-ddm/articles/239935.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/239935.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/239935.html 問題 

      這一ơ有同事在做一個小CASE時遇到問無法解? 整個的需求比較簡? 是需要從資料庫中撈資料出來進行列印, 需求如?
      1. 從tbMain中找W合條g的客?限定條g:只有一{資料的客戶
      2. 查詢tbForeclose, 剔除掉某些客?剔除條g:姓名存在於tbForeclose中的客戶卌從名單中剔除
      3. 從tbDetail中撈客戶的明細資料出來進行列印.關聯條g:依tbMain中客戶ID直接帶出卛_

-- L(同一客戶會有多筆資料)
Create   Table  tbMain (
    aID 
int   identity ( 1 , 1 ),
    pID 
varchar ( 10 not   null ,     -- 客戶ID
    pName  nvarchar ( 20 not   null ,     -- 客戶姓名
    pDoing  varchar ( 20 not   null
);
-- 剔除客戶?僅存攑֮戶姓?
Create   Table  tbForeclose (
    pName 
nvarchar ( 20 not   null      -- 剔除客戶姓名
);
-- 客戶資料明細?/span>
Create   Table  tbDetail (
    pID 
varchar ( 10 primary   key ,     -- 客戶ID(KEY)
    pSex  char ( 1 not   null          -- 客戶其他詳細資料
);

 

CZ數據

嘗試及解?/strong>
      此需求表面來? 實現起來很是單, 只要一條SQL好:

Select
        
*
    
From
        tbDetail
    
Inner   Join  (
        
Select
                pID,pName
            
From
                tbMain
            
Where
                
Not   Exists  ( Select   1   From  tbForeclose  Where  tbForeclose.pName = tbMain.pName)
            
Group   By
                pID,pName
            
Having
                
Count ( * ) = 1
    ) tbMain1 
On  tbMain1.pID = tbDetail.pID

      但此需求在開發時卻有遇C些限制條? 不能這樣d?
      限制條g:
         1. tbMain,tbForeclose,tbDetail三表分別存在g同的DB, 因DB所屬系i各不相? R上環境則會有可能布|在不同DBServer?
         2. tbMaina錄{數極大,索引效率低下.
         3. 三張TABLE是屬於其他的pȝ, 本次需求不允許進行UPDATE的操?
      因此, 需要對應解?

      於限制條g1, 資料處理必須?個步驟進行(見圖上A,B,C), 如圖1:
                        o_1.jpg

      於限制條g2, 主要卡在步驟A的超時上(其後都僅處理到少量資?, 實測時在本機的查詢分析器RUN步驟A的SQLp10分鍾,W合的資料筆數為百萬左右.除非是將ADO連線a為不超? 否則一定會查詢失敗.

      我首先的x是惌提高查詢效率. 
         . E檢查tbMain發現pID列上有烦引而pName上卻? 所以將步驟A進行分解, 僅查詢符合的pID, 實測步驟A1可以?0分鍾以內完成, 見圖2.
                           o_2.jpg
         . 嘗試減少步驟A1的處理筆? 比如先依pID的前兩碼進行分組, 再進行多次查詢, 實測資料量最大的一ipID約在2-3分鍾, 單次資料量減到十萬.
      通過測試的結果可以看到該問題僅通過改善/分解查詢已經不能實現解決. 

      那麽是否能夠步驟A的筆數減到一{呢?
         . 因三檔都不允a進行UPDATE的操? 在處理完TOP 1的一{後因無法對處理過的pID進行標識, 無法獲取下一{的資料.

      既然多種Ҏ都不可行, 那麽只有完全改變處理的程, 通過多添加一張表(為此開D新增的TABLE)並將消耗最大的步驟A交由DB內部來完? 最i解決方?/strong>步驟如下:
      1. 先手工新增臨時TABLE
      
--新增臨時?/span>
Create Table tbTemp (
    aID 
int identity(1,1),
    pID 
varchar(10)
);

      2. 如果是需要多ơRUN的話, 則要先Truncate Table tbTemp, 然後通過Insert Into tbTemp Select....在DB內部完成資料的篩? 由於在客戶端不需要撈一{資? 所以耗時非常的短, 達到U級.
      3. 由於新增檔案是有KEY?Identity), 所以只要拿到批ơ添加的最?最ID值即可通過循環來逐筆處理?
      最i解決方?/strong>如圖3
                              
                           o_3.jpg



]]>
實例解析如何實現行間運算http://www.tkk7.com/tw-ddm/articles/142572.html大大?/dc:creator>大大?/author>Tue, 04 Sep 2007 03:37:00 GMThttp://www.tkk7.com/tw-ddm/articles/142572.htmlhttp://www.tkk7.com/tw-ddm/comments/142572.htmlhttp://www.tkk7.com/tw-ddm/articles/142572.html#Feedback0http://www.tkk7.com/tw-ddm/comments/commentRss/142572.htmlhttp://www.tkk7.com/tw-ddm/services/trackbacks/142572.html
問題

      通常來說實現表級的關聯以及在列之間實N還是比較ҎQ可是利用SQL來實現行間的關聯運算顯得比較困難,這裏׃個實例來解析如何來思考及解決此類的問?br />
表結?/span>

      表結構說?br />         kID               主關鍵字Q例如合約號
         iYear            W幾q度( >= 1)Q連續遞增
         iTime           W幾期[1, 12]Q連續遞增Q根據付ƾ方式有所不同
         D1                  開始日期Q數字類型的民國日期
         PayMode   付款方式Q取?A--q^QS--半年JIQ--季^QM--月^
      要求
         扑ֈ那些 D1 有問的合約。因為根據PayMode來說相同 kID ?D1 變化是存在有規律的,例如如果是A--q^則應該是一q一跻IM--月^則應該是一個月一跻I因此要找到那些蟩的間隔有錯的合約?br />      數據珄
         iYear / iTime 兩列上的數據很亂,有蟩期的現象存在Q例如月J?q??-1q?期?br />         D1 列上有誤Q例如月Jx式下  950505 -- 950718 (正確應該?50505 -- 959604)

      表結構與
我的上一?/font>  CZ2中所用表完全相同Q只不過上一是Z扑ևq度+月䆾不連續的問gQ而這裏則是要解決數據行Row之間的對比,不過這一ơ還是要用到上回述到的那些解決ҎQ只不過要更加複雜?br />

思?/strong>

      1. 要達到間隔的a算Q就要實現行間數據的比Q因此大體的思\應該是用自連接的方式來完成?br />      2. Ҏ數據珄可以看出Q上一中提到的將 iYear + iTime 兩列合併的方案已E不可用Q因為根據現狀這兩列雖然保持唯一和增加,但是增加?Step(步長) 已經不可信Q。根據自連接的特點,我們必須找C個絕可以信賴的遞增列,然後再在該列上實現自連接Q問是這一列該如何選取呢?
      3. D1 列是數字值的民國日期Q要用日期的間隔來判斷需要先該列轉換成正常的西元日期型列才可以實現?br />

解決Ҏ

      1. 扑ֈ那?Step 可以信賴的遞增列?br />         既然 iYear + iTime ?Step 不可信賴可是兩列唯一和增加還是可用的Q因為可以用 自行構徏Identity的方?/a> 來據此生成一個可用的 Identity 列?br />      2. D1的西元日期型轉換Q可以用 qր用於SQL的日期轉換函?vb) 中功?所C的 parseDate(strSQL) 來實現?br />      3. 問題日期的間隔這裏只簡單的按大?2?月來判斷?br />
SQL語句
SQL語句

         從該SQL語句可以看到Z實現自連接Q構Z2張表 AL(2-14? ?AR(16-28?Q兩表的內容完全一_中間使用了自定義 Identity ?Index1 (4-11? Q然後再AL ?AR 實現錯值連接(29??br />         連接後表a錄的日期間隔運,攑֜Where子句?30-38?Q這裏寫的是僞語句Q需要用前面提到?VB函數轉換才可以運行,不過這樣看v來就會明子許多?br />

         可以看到Q只要在處理裏靈z運用各E技巧就可以解決更加複雜的邏輯?/font>


]]>
վ֩ģ壺 һƵѹۿ| ձƵ| һëƬ߲| ˳ɵӰ߹ۿ| þӰۺ| ձһۺϾþa| 4399Ӱѹۿֱ| ߹ۿѻվ| JIZZJIZZŮ| þþþþƷAV| Ʒާv벥| www.޾Ʒ| 99ƵѾƷǿ6| ˼˼reѾƷƵ66| ˿Ƶ| ޾ƷպAV| պһ| һۺ߲| ޾Ʒav߹ۿ| AVպƷһ| պƷƵ | һѹۿwwwƵ| һƬѿ| Ļav벻| һһëƬѲ| ̱߳ˬƵ99| ޾ƷþþþAƬԾ| ޹Ʒһ| ŷ޴ɫУ԰С˵| ɫʮʮɫ| ޹ۺ91Ʒ鶹| ޹ƷһƬ| ٸ17p| ˾þۺij| ޾Ʒ˳ëƬ | Ʒ˿߲| ҹþþþþ| һƵ߹ۿ| þþþav| ѿƬ߹ۿ| һĻ|