<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4428257381149033865</id><updated>2012-01-12T02:25:05.556+08:00</updated><category term='BASH'/><category term='MVC'/><category term='dbm'/><category term='C'/><category term='自動化'/><category term='Performance Tuning'/><category term='SQL Server'/><category term='AJAX'/><category term='WebDevelop'/><category term='SELinux'/><category term='Windows'/><category term='Security'/><category term='Firewall'/><category term='Oracle'/><category term='OpenVPN'/><category term='ASP.NET'/><category term='UTM'/><category term='C++'/><category term='Multi-Thread'/><category term='VPN'/><category term='Backup'/><category term='Git'/><category term='GridGain'/><category term='Framework'/><category term='Software'/><category term='計算機結構'/><category term='Apache'/><category term='OOAD'/><category term='Untangle'/><category term='DocProject'/><category term='Linux Programming'/><category term='HTML5'/><category term='ZeroShell'/><category term='LINQ'/><category term='Service'/><category term='JVM'/><category term='jQuery'/><category term='MySQL'/><category term='PL-SQL'/><category term='TCP-IP'/><category term='XML'/><category term='Java'/><category term='Blogger'/><category term='LDAP'/><category term='ADO.NET'/><category term='PHP'/><category term='Unicode'/><category term='Assembly'/><category term='PostgreSQL'/><category term='Joomla'/><category term='QoS'/><category term='Linux'/><category term='Debug'/><category term='CSharp'/><category term='Grid'/><category term='Ubuntu'/><category term='T-SQL'/><category term='Wiki'/><category term='JavaScript'/><category term='WPF'/><category term='Silverlight'/><category term='OS'/><category term='.NET'/><title type='text'>小信豬的原始部落</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default?start-index=101&amp;max-results=100'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>251</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2807103113954061995</id><published>2011-09-21T21:35:00.000+08:00</published><updated>2011-09-27T17:27:45.887+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>[ASP.NET] MVC 3 相關參考資料</title><content type='html'>&lt;a href="http://kkbruce.blogspot.com/2011/03/aspnet-mvc-3.html"&gt;KingKong Bruce記事: ASP.NET MVC 3概觀正體中文版&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mvcmusicstore.codeplex.com/"&gt;MVC Music Store - Tutorial Application&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2807103113954061995?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2807103113954061995/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2807103113954061995' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2807103113954061995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2807103113954061995'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/09/aspnet-mvc-3.html' title='[ASP.NET] MVC 3 相關參考資料'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-5223458624346237572</id><published>2011-09-21T17:58:00.003+08:00</published><updated>2011-09-21T17:59:29.709+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ADO.NET'/><title type='text'>[ADO.NET] Entity Framework 相關參考資料</title><content type='html'>&lt;a href="http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/12/17/ado-net-entity-framework-tools-stored-procedures.aspx"&gt;ADO.Net Entity Framework Tools: Stored Procedures - Guy Burstein's Blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-5223458624346237572?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/5223458624346237572/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=5223458624346237572' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/5223458624346237572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/5223458624346237572'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/09/aspnet-adonet-entity-framework.html' title='[ADO.NET] Entity Framework 相關參考資料'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4131732729739249080</id><published>2011-09-20T10:04:00.003+08:00</published><updated>2011-09-20T10:04:42.927+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>[ASP.NET] jQuery AJAX 應用相關參考資料</title><content type='html'>&lt;a href="http://www.dotblogs.com.tw/hatelove/archive/2009/12/22/jqueryajax.aspx"&gt;[ASP.NET &amp;amp; jQuery]使用jQuery的Ajax存取資料(ashx,aspx,asmx) - In 91- 點部落&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4131732729739249080?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4131732729739249080/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4131732729739249080' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4131732729739249080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4131732729739249080'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/09/aspnet-jquery-ajax.html' title='[ASP.NET] jQuery AJAX 應用相關參考資料'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8004395574281768042</id><published>2011-09-16T15:54:00.002+08:00</published><updated>2011-09-21T16:17:30.857+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance Tuning'/><title type='text'>[ASP.NET] Performance Tuning</title><content type='html'>&lt;div&gt;1. 使用 SqlCommand 搭配 SqlDataReader 時，記得先呼叫 &lt;b&gt;SqlCommand.Cancel()&lt;/b&gt; 再呼叫 &lt;b&gt;SqlDataReader.Close()&lt;/b&gt;，順序錯誤效能會低落很多&lt;br /&gt;&amp;nbsp; &amp;nbsp; (若僅呼叫 SqlDataReader.Close() 效能也會很低落)&lt;br /&gt;&lt;br /&gt;2. 資料來源控制項的 DataSourceMode 要根據實際需求選擇&lt;br /&gt;&amp;nbsp; &amp;nbsp; (選擇 DataSet 模式，功能雖然強大，但耗費資訊)&lt;br /&gt;&lt;br /&gt;3. 處理大量資料避免使用 ADO.NET Entity Framework 這一類的工具，速度很慢&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8004395574281768042?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8004395574281768042/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8004395574281768042' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8004395574281768042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8004395574281768042'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/09/aspnet-performance-tuning.html' title='[ASP.NET] Performance Tuning'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-426192907803233397</id><published>2011-08-03T11:11:00.000+08:00</published><updated>2011-08-03T11:11:41.020+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[.NET] 如何不安裝 Oracle Client 並與 Oracle DB 連線</title><content type='html'>恩.......我目前手邊這一台 NB 真的很怪....無法安裝 Oracle Client....&lt;br /&gt;&lt;br /&gt;但是我要連 Oracle 阿!! 這該怎辦ㄌㄟ....&lt;br /&gt;&lt;br /&gt;上網找了一下，必須要在程式執行目錄(bin/)中，放入以下五個 DLL 檔案：&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Oracle.DataAccess.dll&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;oci.dll&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;OraOps11w.dll&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;oraociei11.dll&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;msvcr71.dll&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;這些檔案可以在有安裝 Oracle Client 的電腦上找到....我是請同事找給我的.....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;另外在連線字串部分，沒辦法使用 OracleDBConnectionStringBuilder 物件產生連線字串，必須用自行組成語法的方式：&lt;/div&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: red; font-size: x-small;"&gt;string DBConnectionString = @"Data Source=(DESCRIPTION = (ADDRESS_LIST =&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: red; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (ADDRESS = (PROTOCOL = TCP)(HOST = 這是 Oracle Server IP)(PORT = 1521)) )&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: red; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (CONNECT_DATA = (SID = 這裡放SID)(SERVER = DEDICATED) ) )&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: red; font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ;Persist Security Info=True;User ID=這是使用者帳號;Password=使用者密碼;";&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;最後程式中引用 Oracle.DataAccess.dll 作為參考，相關的 Oracle API 就可以使用囉!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-426192907803233397?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/426192907803233397/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=426192907803233397' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/426192907803233397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/426192907803233397'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/08/net-oracle-client-oracle-db.html' title='[.NET] 如何不安裝 Oracle Client 並與 Oracle DB 連線'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1761568552847100908</id><published>2011-06-01T15:23:00.006+08:00</published><updated>2011-07-15T20:46:21.713+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Multi-Thread'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ] 集合已修改; 列舉作業可能尚未執行??</title><content type='html'>今天同事在寫程式遇到這問題.....&lt;br&gt;&lt;br&gt;問我.... LINQ 可以在 multi-thread 環境下執行嗎?? 程式起來一直有問題......&lt;br&gt;&lt;br&gt;我心裡想......怎麼會不行? 如果不行，微軟不就搞了一個大飛機了..........?&lt;br&gt;&lt;br&gt;後來發現其實跟 LINQ 無關，而是在進行列舉作業時不能去修改集合的值&lt;br&gt;&lt;br&gt;&lt;a href="http://godleon.blogspot.com/2011/06/linq.html#more"&gt;閱讀更多 »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1761568552847100908?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1761568552847100908/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1761568552847100908' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1761568552847100908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1761568552847100908'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/06/linq.html' title='[LINQ] 集合已修改; 列舉作業可能尚未執行??'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-SLfXlcfXHzA/TeXlqQbX-MI/AAAAAAAAC1E/4JTgpKx3Hw8/s72-c/LINQ_Enumeration.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2295975559893818450</id><published>2011-06-01T11:16:00.000+08:00</published><updated>2011-06-01T11:16:14.352+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><title type='text'>[JVM] Performance Tuning 相關資源蒐集</title><content type='html'>&lt;a href="http://gq913.iteye.com/blog/157276"&gt;JVM調優總結- See World - ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/518623"&gt;JVM調優總結（一）-- 一些概念- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/519471"&gt;JVM調優總結（二）-一些概念- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/520228"&gt;JVM調優總結（三）-基本垃圾回收算法- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/523230"&gt;JVM調優總結（四）-垃圾回收面臨的問題- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.blogger.com/"&gt;&lt;/a&gt;&lt;span id="goog_1848827907"&gt;&lt;/span&gt;&lt;span id="goog_1848827908"&gt;&lt;/span&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/524024"&gt;JVM調優總結（五）-分代垃圾回收詳述1 - 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/528034"&gt;JVM調優總結（六）-分代垃圾回收詳述2 - 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/538582"&gt;JVM調優總結（七）-典型配置舉例1 - 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/545015"&gt;JVM調優總結（八）-典型配置舉例2 - 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/548472"&gt;JVM調優總結（九）-新一代的垃圾回收算法- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/552456"&gt;JVM調優總結（十）-調優方法- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/558619"&gt;JVM調優總結（十一）-反思- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pengjiaheng.iteye.com/blog/558620"&gt;JVM調優總結（十二）-參考資料- 和你在一起- ITeye技術網站&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2295975559893818450?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2295975559893818450/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2295975559893818450' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2295975559893818450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2295975559893818450'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/06/jvm-performance-tuning.html' title='[JVM] Performance Tuning 相關資源蒐集'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7580341768236975658</id><published>2011-05-31T10:34:00.002+08:00</published><updated>2011-06-01T11:16:49.073+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='JVM'/><title type='text'>[Windows] 修改 JVM 啟動參數</title><content type='html'>今天早上為了 H2 執行五六個小時後會出現 out of memory 的問題在頭痛...&lt;br /&gt;&lt;br /&gt;上到 Google Group 查了一下，有人建議先把 JVM 的 heap 開大一點試試看....&lt;br /&gt;&lt;br /&gt;於是.......問題來了，要怎麼開大??&lt;br /&gt;&lt;br /&gt;在 Linux 裡面可以直接透過 Alias 的方式解決.......&lt;br /&gt;&lt;br /&gt;那 Windows 呢? 答案就是設定一個名稱為 "&lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;_JAVA_OPTIONS&lt;/span&gt;&lt;/b&gt;" 的環境變數&lt;br /&gt;&lt;br /&gt;值的部分就設定為 "&lt;b&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;-Xms512m -Xmx1024m&lt;/span&gt;&lt;/b&gt;" 應該是很夠用了....&lt;br /&gt;&lt;br /&gt;再來繼續長時間測試 H2 看看.....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7580341768236975658?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7580341768236975658/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7580341768236975658' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7580341768236975658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7580341768236975658'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/05/windows-jvm.html' title='[Windows] 修改 JVM 啟動參數'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7519566974248412353</id><published>2011-05-30T17:38:00.008+08:00</published><updated>2011-07-20T11:33:48.443+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTML5'/><title type='text'>[HTML5] 學習資源</title><content type='html'>&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;基本觀念&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.w3schools.com/html5/default.asp"&gt;W3Schools.com - HTML5 Tutorial&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://inspire.twgg.org/c/programming/html-css/html5-started-teaching.html"&gt;HTML5入門教學 | InspireGate 派克空間&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: large;"&gt;&lt;b&gt;工具&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.modernizr.com/"&gt;Modernizr&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://yepnopejs.com/"&gt;yepnope.js | A Conditional Loader For Your Polyfills!&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills"&gt;HTML5 Cross Browser Polyfills - GitHub&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://html5boilerplate.com/"&gt;HTML5 Boilerplate - A rock-solid default template for HTML5 awesome.&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7519566974248412353?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7519566974248412353/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7519566974248412353' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7519566974248412353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7519566974248412353'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/05/html5.html' title='[HTML5] 學習資源'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3896809816686716771</id><published>2011-05-26T16:19:00.003+08:00</published><updated>2011-06-08T17:21:09.304+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ] 如何直接更改物件集合中的物件值而不建立新物件</title><content type='html'>用過 LINQ 的人應該會對 LINQ 處理資料集合的功力印象深刻....&lt;br /&gt;&lt;br /&gt;但....LINQ 是 Query 阿! 不是 Update!&lt;br /&gt;&lt;br /&gt;那如果我只是要針對物件集合中的某幾個物件進行值的變更.......要怎麼作呢....??&lt;br /&gt;&lt;br /&gt;答案是 =&amp;gt; 只要自己撰寫一個 &lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;extension method&lt;/span&gt;&lt;/b&gt;，method 中回傳原本的物件集合&lt;br /&gt;&lt;br /&gt;在網路上找到一個很不錯的參考範例連結：&lt;br /&gt;&lt;a href="http://blog.robvolk.com/2009/05/linq-select-object-but-change-some.html"&gt;LINQ: Select an object, but change some properties without creating a new object (Rob Volk's Blog)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;以下寫了一個簡單的 sample&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-jEoyLd-ndio/Td8c6ZlCFnI/AAAAAAAAC1A/pLQcDSfz5M0/s1600/LINQ_WithoutCreatingNewObject.PNG" imageanchor="1"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-jEoyLd-ndio/Td8c6ZlCFnI/AAAAAAAAC1A/pLQcDSfz5M0/s1600/LINQ_WithoutCreatingNewObject.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;但有一點真的需要注意的是，&lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;這種方式只能用在物件集合中，若是用在基本型態的資料集合中(例如：整數陣列、整數 List) 則沒有效果&lt;/span&gt;&lt;/b&gt;......&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2011/06/08 Updated:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;今天有找到初始化陣列的方式囉! 只要使用 extension method 就可以簡單達成了....以下為範例：&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-lukJgBWVOME/Te8-0uL8TbI/AAAAAAAAC1g/0pdueJecbMI/s1600/ExtensionMethod_InitialArray.PNG" imageanchor="1" style="margin-left: 0em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-lukJgBWVOME/Te8-0uL8TbI/AAAAAAAAC1g/0pdueJecbMI/s1600/ExtensionMethod_InitialArray.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3896809816686716771?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3896809816686716771/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3896809816686716771' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3896809816686716771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3896809816686716771'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2011/05/linq.html' title='[LINQ] 如何直接更改物件集合中的物件值而不建立新物件'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-jEoyLd-ndio/Td8c6ZlCFnI/AAAAAAAAC1A/pLQcDSfz5M0/s72-c/LINQ_WithoutCreatingNewObject.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-9183411198473963437</id><published>2010-08-31T21:00:00.001+08:00</published><updated>2010-08-31T21:02:41.687+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>[Joomla!] Session 控管</title><content type='html'>&lt;iframe width="100%" height="750px" marginwidth="0" #marginheight="0" scrolling="no" frameborder="0" align="center" src="https://docs.google.com/document/pub?id=1ZaD7MVfBpXTV0fsbFivFkWriNl0KLjtBmK_b2cfy1SM&amp;amp;embedded=true"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-9183411198473963437?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/9183411198473963437/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=9183411198473963437' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9183411198473963437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9183411198473963437'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/08/joomla-session.html' title='[Joomla!] Session 控管'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2533740404984871536</id><published>2010-08-22T15:00:00.004+08:00</published><updated>2010-08-22T15:03:16.156+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>[Joomla!] Database</title><content type='html'>&lt;iframe width="100%" height="350%" marginwidth="0" #marginheight="0" scrolling="no" frameborder="0" align="center" src="https://docs.google.com/document/pub?id=1PmGvPg8B29htK2EegKXeZ1sev3A0_kvK1nxFGXoEzlk&amp;amp;embedded=true"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2533740404984871536?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2533740404984871536/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2533740404984871536' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2533740404984871536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2533740404984871536'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/08/joomla-database.html' title='[Joomla!] Database'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6019530965068980431</id><published>2010-08-22T14:52:00.009+08:00</published><updated>2010-08-22T14:59:18.105+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='Joomla'/><title type='text'>[Joomla!] Getting Start</title><content type='html'>&lt;iframe width="100%" height="126%" marginwidth="0" #marginheight="0" scrolling="no" frameborder="0" align="center" src="https://docs.google.com/document/pub?id=1Ok2lyOIBdafLhghD9rvDvt58_NyfKDuqvbS7q2-TZCU&amp;amp;embedded=true"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6019530965068980431?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6019530965068980431/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6019530965068980431' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6019530965068980431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6019530965068980431'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/08/aa.html' title='[Joomla!] Getting Start'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8485394243068900567</id><published>2010-03-12T11:26:00.002+08:00</published><updated>2010-03-12T11:32:57.914+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux Programming'/><title type='text'>[Linux Programming] 在 Ubuntu 中使用 C 語言連結 MySQL</title><content type='html'>首先.......必須安裝 MySQL server，一般來說安裝 "mysql-server" 都可以裝到目前最新版的套件&lt;br /&gt;&lt;br /&gt;&lt;div&gt;接著要安裝開發程式所需要的 library：&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Ubuntu 8.04 =&amp;gt; &lt;b&gt;&lt;span style="color:#FF0000;"&gt;libmysqlclient15-dev&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;相關的 header 檔案都會放在 &lt;b&gt;/usr/include/&lt;/b&gt; 裡面，而實際運作的函式庫則會存在 &lt;b&gt;/usr/lib/mysql&lt;/b&gt; 中&lt;/div&gt;&lt;br /&gt;&lt;div&gt;若是撰寫 mysql 相關程式時，編譯方式如下：&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;gcc &amp;lt;程式名稱&amp;gt; &lt;span style="color:#0000FF;"&gt;-I /usr/include/mysql&lt;/span&gt; &lt;span style="color:#FF0000;"&gt;-L /usr/lib/mysql&lt;/span&gt; &lt;span style="color:#38761D;"&gt;-l mysqlclient&lt;/span&gt; -o &amp;lt;輸出檔案名稱&amp;gt;&lt;/b&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8485394243068900567?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8485394243068900567/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8485394243068900567' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8485394243068900567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8485394243068900567'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/03/linux-programming-ubuntu-c-mysql.html' title='[Linux Programming] 在 Ubuntu 中使用 C 語言連結 MySQL'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7615428255382081171</id><published>2010-03-09T16:42:00.002+08:00</published><updated>2010-03-09T16:51:04.345+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Git'/><title type='text'>[Git] 在 Windows 上使用 Git</title><content type='html'>Git &amp;#32893;&amp;#35498;&amp;#26159;&amp;#27604; cvs, subversion &amp;#36996;&amp;#22909;&amp;#29992;&amp;#30340; version control system &amp;#38463;!!&lt;br&gt;&lt;br&gt;&lt;div&gt;&amp;#28858;&amp;#20309;&amp;#35201;&amp;#29992; Git &amp;#38463;?? &amp;#22240;&amp;#28858;&amp;#20778;&amp;#40670;&amp;#24456;&amp;#22810;&amp;#38463;! &amp;#35443;&amp;#32048;&amp;#35498;&amp;#26126;&amp;#21487;&amp;#20197;&amp;#30475; =&amp;gt;&amp;nbsp;&lt;a href="http://zh-tw.whygitisbetterthanx.com/" id="wps5" style="color:#551a8b" title="Why Git is Better Than X"&gt;Why Git is Better Than X&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;#36889;&amp;#19968;&amp;#31687;&amp;#25991;&amp;#31456;~&lt;/div&gt;&lt;br&gt;&lt;div&gt;Git &amp;#22823;&amp;#27010;&amp;#26377;&amp;#20197;&amp;#19979;&amp;#29305;&amp;#33394;&amp;#65306;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&amp;#27599;&amp;#20491; local &amp;#31471;&amp;#37117;&amp;#26377;&amp;#33258;&amp;#24049;&amp;#30340; repository&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&amp;#29305;&amp;#33394;&amp;#28858; branch + merge&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&amp;#36969;&amp;#21512;&amp;#38283;&amp;#30332;&amp;#20154;&amp;#25976;&amp;#30526;&amp;#22810;&amp;#30340;&amp;#22823;&amp;#22411;&amp;#23560;&amp;#26696;(&amp;#30070;&amp;#28982;&amp;#23567;&amp;#22411;&amp;#23560;&amp;#26696;&amp;#20063;&amp;#26159;&amp;#27794;&amp;#26377;&amp;#21839;&amp;#38988;&amp;#28404;)&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;div&gt;&amp;#22823;&amp;#37096;&amp;#20998;&amp;#20351;&amp;#29992; git &amp;#30340;&amp;#20154;&amp;#37117;&amp;#26159;&amp;#22312; Linux &amp;#30340;&amp;#24179;&amp;#21488;&amp;#19978;&amp;#20351;&amp;#29992;&amp;#65292;&amp;#20294;&amp;#35201;&amp;#24590;&amp;#40636;&amp;#22312; Windows &amp;#19978;&amp;#38754;&amp;#20351;&amp;#29992;&amp;#21602;?&lt;/div&gt;&lt;br&gt;&lt;div&gt;&amp;#31777;&amp;#21934;&amp;#35498;&amp;#26126;&amp;#27493;&amp;#39519;&amp;#22914;&amp;#19979;&amp;#65306;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;&amp;#19979;&amp;#36617; Windows &amp;#29992;&amp;#30340; git &amp;#26680;&amp;#24515;&amp;#31243;&amp;#24335;&amp;#65292;&amp;#22312; git &amp;#23448;&amp;#32178;&amp;#19978;&amp;#28858; &lt;b&gt;&lt;a href="http://code.google.com/p/msysgit/" id="ni2c" title="msysgit"&gt;msysgit&lt;/a&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&amp;#22312;&amp;#25152;&amp;#35201;&amp;#36914;&amp;#34892;&amp;#29256;&amp;#26412;&amp;#31649;&amp;#29702;&amp;#30340;&amp;#36039;&amp;#26009;&amp;#22846;&amp;#19978;&amp;#25353;&amp;#28369;&amp;#40736;&amp;#21491;&amp;#37749;&amp;#65292;&amp;#36984;&amp;#25799; &lt;b&gt;Git Bash Here&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&amp;#25509;&amp;#33879;&amp;#26371;&amp;#36339;&amp;#20986;&amp;#19968;&amp;#20491;&amp;#27169;&amp;#25836; bash &amp;#29872;&amp;#22659;&amp;#30340;&amp;#35222;&amp;#31383;&amp;#65292;&amp;#25509;&amp;#33879;&amp;#23601;&amp;#21487;&amp;#20197;&amp;#36319; Linux &amp;#19968;&amp;#27171;&amp;#38283;&amp;#22987;&amp;#20351;&amp;#29992; Git &amp;#22217;!&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;div id="hw-e" style="text-align:left"&gt;&lt;img src="http://docs.google.com/File?id=ddzmw8vs_164fhtcgzcs_b" style="height:375.820628px;width:648px"&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;===== &amp;#20197;&amp;#19979;&amp;#35498;&amp;#26126;&amp;#26368;&amp;#22522;&amp;#26412;&amp;#30340;&amp;#20351;&amp;#29992;&amp;#26041;&amp;#24335; =====&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;font color="#38761D"&gt;#&amp;#21021;&amp;#22987;&amp;#21270; local repository&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&amp;gt; &lt;b&gt;git init&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;font color="#38761D"&gt;#&amp;#23559;&amp;#30446;&amp;#37636;&amp;#20013;&amp;#30340;&amp;#27284;&amp;#26696;&amp;#20840;&amp;#37096;&amp;#21152;&amp;#20837; Staging Area&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&amp;gt; &lt;b&gt;git add .&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;font color="#38761D"&gt;#&amp;#23559; Staging Area &amp;#20013;&amp;#30340;&amp;#27284;&amp;#26696;&amp;#21152;&amp;#20837; local repository &amp;#20013;&lt;/font&gt;&lt;/div&gt;&amp;gt; &lt;b&gt;git commit -a&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;div&gt;&lt;font color="#38761D"&gt;#&amp;#31227;&amp;#21205;&amp;#33267; master branch (&amp;#27491;&amp;#24120;&amp;#29376;&amp;#27841;&amp;#19979; branch &amp;#26371;&amp;#38928;&amp;#35373;&amp;#22312; master)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&amp;gt; &lt;b&gt;git checkout master&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;&lt;font color="#38761D"&gt;#&amp;#23559;&amp;#36039;&amp;#26009; push &amp;#33267;&amp;#36960;&amp;#31471;&amp;#30340; repository (&amp;#20197; gitorious &amp;#28858;&amp;#20363;)&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&amp;gt; &lt;b&gt;git remote add origin &amp;lt;git push url&amp;gt;&lt;/b&gt;&lt;br&gt;&amp;gt; &lt;b&gt;git push origin master&lt;/b&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font color="#FF0000"&gt;&amp;#12304;&amp;#20633;&amp;#35387;&amp;#12305;&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;div&gt;&amp;#22312;&amp;#23559;&amp;#27284;&amp;#26696; push &amp;#21040;&amp;#36960;&amp;#31471; git server &amp;#20043;&amp;#21069;&amp;#65292;&amp;#38656;&amp;#35201;&amp;#25226;&amp;#21152;&amp;#23494;&amp;#29992;&amp;#30340; key pair &amp;#28310;&amp;#20633;&amp;#22909;&amp;#65292;&amp;#21487;&amp;#20197;&amp;#36879;&amp;#36942;&amp;#20197;&amp;#19979;&amp;#25351;&amp;#20196;&amp;#29986;&amp;#29983;&amp;#65306;&lt;div&gt;&amp;gt; &lt;b&gt;ssh-keygen -rsa&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&amp;#25509;&amp;#33879;&amp;#25226;&amp;#20841;&amp;#20491;&amp;#27284;&amp;#26696;&amp;#37117;&amp;#25918;&amp;#21040;&amp;nbsp;&lt;b&gt;&lt;font color="#0000FF"&gt;C:\Documents and Settings\&amp;lt;USER NAME&amp;gt;\.ssh&lt;/font&gt;&lt;/b&gt;&amp;nbsp;&amp;#65292;&amp;#20006;&amp;#23559; public key &amp;#30340;&amp;#20839;&amp;#23481;&amp;#21152;&amp;#20837;&amp;#21040; gitorious &amp;#30340;&amp;#32178;&amp;#31449;&amp;#19978;&amp;#21363;&amp;#21487;&amp;#12290;&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;h3&gt;&amp;#30456;&amp;#38364;&amp;#36899;&amp;#32080;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://zh-tw.whygitisbetterthanx.com/" id="l0lw" title="Why Git is Better Than X"&gt;Why Git is Better Than X&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a href="http://nathanj.github.com/gitguide/" id="kini" title="An Illustrated Guide to Git on Windows"&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://nathanj.github.com/gitguide/" id="bb.x" title="An Illustrated Guide to Git on Windows"&gt;An Illustrated Guide to Git on Windows&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.qweruiop.org/nchcrails/posts/49" id="f7y5" title="&amp;#22283;&amp;#32178;&amp;#20013;&amp;#24515; Web 2.0 &amp;#25216;&amp;#34899;&amp;#25512;&amp;#24291; &amp;raquo; Blog Archive &amp;raquo; Git &amp;#21407;&amp;#22987;&amp;#30908;&amp;#31649;&amp;#29702;"&gt;&amp;#22283;&amp;#32178;&amp;#20013;&amp;#24515; Web 2.0 &amp;#25216;&amp;#34899;&amp;#25512;&amp;#24291; &amp;raquo; Blog Archive &amp;raquo; Git &amp;#21407;&amp;#22987;&amp;#30908;&amp;#31649;&amp;#29702;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://plog.longwin.com.tw/my_note-unix/2009/05/19/git-learn-initial-command-2009" id="nb97" title="Git &amp;#21021;&amp;#23416;&amp;#31558;&amp;#35352; - &amp;#25351;&amp;#20196;&amp;#25805;&amp;#20316;&amp;#25945;&amp;#23416; | Tsung&amp;#39;s Blog"&gt;Git &amp;#21021;&amp;#23416;&amp;#31558;&amp;#35352; - &amp;#25351;&amp;#20196;&amp;#25805;&amp;#20316;&amp;#25945;&amp;#23416; | Tsung&amp;#39;s Blog&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://josephjiang.com/entry.php?id=308" id="ejc_" title="Git Study"&gt;Git Study&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7615428255382081171?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7615428255382081171/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7615428255382081171' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7615428255382081171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7615428255382081171'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/03/git-windows-git.html' title='[Git] 在 Windows 上使用 Git'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1299045694981398108</id><published>2010-03-07T16:30:00.003+08:00</published><updated>2010-03-07T16:39:21.860+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='dbm'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux Programming'/><title type='text'>[Linux Programming] 在 Ubuntu 中使用 dbm 資料庫</title><content type='html'>在 ubuntu 中 dbm 相關開發套件是不會預先安裝的，因此如果要使用的話，必須安裝「&lt;span style="font-weight:bold;"&gt;libgdbm-dev&lt;/span&gt;」套件。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;而由於安裝的是 gdbm 套件，若要使用 gdbm 的相關函式當然沒問題，但若是要使用 ndbm 的相關函式，則必須進行相容性的轉換，作法如下：&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;在程式中 &lt;span class="Apple-style-span"  style="color:#FF0000;"&gt;include gdbm-ndbm.h&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;編譯時加上 &lt;span class="Apple-style-span"  style="color:#FF0000;"&gt;-l gdbm_compat -l gdbm&lt;/span&gt; 兩個參數以連結函式庫&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;函式庫說明可以參考以下連結：&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/hardy/man7/ndbm.h.7posix.html"&gt;Ubuntu Manpage: ndbm.h - definitions for ndbm database operations&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://manpages.ubuntu.com/manpages/hardy/man3/gdbm.3gdbm.html"&gt;Ubuntu Manpage: GDBM - The GNU database manager. Includes dbm and ndbm compatability.&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1299045694981398108?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1299045694981398108/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1299045694981398108' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1299045694981398108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1299045694981398108'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/03/linux-programming-ubuntu-dbm.html' title='[Linux Programming] 在 Ubuntu 中使用 dbm 資料庫'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2372478792922250860</id><published>2010-03-01T13:51:00.005+08:00</published><updated>2011-09-21T15:29:27.196+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><title type='text'>[C#] Socket Programming</title><content type='html'>socket programming 的重點大概有幾個：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;有 server &amp;amp; client 兩端&lt;br /&gt;&lt;/li&gt;&lt;li&gt;server 只有一個，而 client 有可能會多個&lt;br /&gt;&lt;/li&gt;&lt;li&gt;server 可設定監聽(listen)的 port number&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;以下直接用範例來說明囉! &lt;/div&gt;&lt;div&gt;(其中 SocketServer 跟新的 client 連線後，會交給 ClientRequestHandler 處理)&lt;/div&gt;&lt;br /&gt;&lt;b&gt;SocketServer.cs&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;using System.Net.Sockets;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;&lt;br /&gt;namespace SocketConn&lt;br /&gt;{&lt;br /&gt;    class SocketServer&lt;br /&gt;    {&lt;br /&gt;        #region private property&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// socket server TCP port number&lt;br /&gt;        /// &lt;/summary&gt;        private int _PortNumber;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// TCP Listener&lt;br /&gt;        /// &lt;/summary&gt;        private TcpListener _Listener;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 用來處理 Listener 工作的執行緒&lt;br /&gt;        /// &lt;/summary&gt;        private BackgroundWorker _bgwServer = new BackgroundWorker();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// socker client 識別編號&lt;br /&gt;        /// &lt;/summary&gt;        private int _ClientNo = 0;&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region static public property&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 工作進行中產生之訊息&lt;br /&gt;        /// &lt;/summary&gt;        public static List&lt;string&gt; sMessages = new List&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region constructor&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// constructor&lt;br /&gt;        /// &lt;/summary&gt;        /// &lt;param name="inPortNumber" /&gt;&lt;br /&gt;socket server TCP port number&lt;br /&gt;        public SocketServer(int inPortNumber)&lt;br /&gt;        {&lt;br /&gt;            this._PortNumber = inPortNumber;&lt;br /&gt;&lt;br /&gt;            //委派事件&lt;br /&gt;            _bgwServer.DoWork += new DoWorkEventHandler(_bgwServer_DoWork);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region public method&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 開始監聽&lt;br /&gt;        /// &lt;/summary&gt;        public void Start()&lt;br /&gt;        {&lt;br /&gt;            if (!_bgwServer.IsBusy)&lt;br /&gt;                _bgwServer.RunWorkerAsync();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region BackgroundWorker&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// 處理 Listener 工作&lt;br /&gt;        /// &lt;/summary&gt;        /// &lt;param name="sender" /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;param name="e" /&gt;&lt;br /&gt;&lt;br /&gt;        private void _bgwServer_DoWork(object sender, DoWorkEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                //若 TCP Listner 正在工作，則停止&lt;br /&gt;                if (_Listener != null)&lt;br /&gt;                    _Listener.Stop();&lt;br /&gt;&lt;br /&gt;                //初始化 TCPListener&lt;br /&gt;                _Listener = new TcpListener(IPAddress.Any, _PortNumber);&lt;br /&gt;&lt;br /&gt;                //啟動 listener&lt;br /&gt;                _Listener.Start();&lt;br /&gt;                sMessages.Add(" &amp;gt;&amp;gt; " + "Server Started");&lt;br /&gt;&lt;br /&gt;                //========== 持續接受監聽 socket client 的連線 ========== (start)&lt;br /&gt;                while (true)&lt;br /&gt;                {&lt;br /&gt;                    //監聽到來自 socket client 的連線要求&lt;br /&gt;                    TcpClient socket4Client = _Listener.AcceptTcpClient();&lt;br /&gt;&lt;br /&gt;                    //累加 socket client 識別編號&lt;br /&gt;                    _ClientNo++;&lt;br /&gt;                    sMessages.Add(" &amp;gt;&amp;gt; " + "Client Request No:" + Convert.ToString(_ClientNo) + " started!");&lt;br /&gt;&lt;br /&gt;                    //產生 BackgroundWorker 負責處理每一個 Socket Client 的要求&lt;br /&gt;                    ClientRequestHandler handler = new ClientRequestHandler(_ClientNo, socket4Client);&lt;br /&gt;                    handler.DoCommunicate();&lt;br /&gt;                }&lt;br /&gt;                //========== 持續接受監聽 socket client 的連線 ========== (end)&lt;br /&gt;            }&lt;br /&gt;            catch (Exception exp)&lt;br /&gt;            {&lt;br /&gt;                sMessages.Add(exp.ToString());&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;/string&gt;&lt;/string&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ClientRequestHandler.cs&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;using System.Net.Sockets;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;&lt;br /&gt;namespace SocketConn&lt;br /&gt;{&lt;br /&gt;    class ClientRequestHandler&lt;br /&gt;    {&lt;br /&gt;        #region private property&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// socket client 識別號碼&lt;br /&gt;        /// &lt;/summary&gt;        private int _ClientNo;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// socket client reuqest&lt;br /&gt;        /// &lt;/summary&gt;        private TcpClient _TcpClient;&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region constructor&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// constructor&lt;br /&gt;        /// &lt;/summary&gt;        /// &lt;param name="inClientNo" /&gt;&lt;br /&gt;socket client 識別號碼&lt;br /&gt;        /// &lt;param name="inTcpClient" /&gt;&lt;br /&gt;socket client reuqest&lt;br /&gt;        public ClientRequestHandler(int inClientNo, TcpClient inTcpClient)&lt;br /&gt;        {&lt;br /&gt;            this._ClientNo = inClientNo;&lt;br /&gt;            this._TcpClient = inTcpClient;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region public method&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// server &amp;amp; client 間相互進行通訊&lt;br /&gt;        /// &lt;/summary&gt;        public void DoCommunicate()&lt;br /&gt;        {&lt;br /&gt;            //產生 BackgroundWorker 負責處理每一個 socket client 的 reuqest&lt;br /&gt;            BackgroundWorker bgwSocket = new BackgroundWorker();&lt;br /&gt;            bgwSocket.DoWork += new DoWorkEventHandler(bgwSocket_DoWork);&lt;br /&gt;            bgwSocket.RunWorkerAsync();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region BackgroundWorker&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 處理 socket client request&lt;br /&gt;        /// &lt;/summary&gt;        private void bgwSocket_DoWork(object sender, DoWorkEventArgs e)&lt;br /&gt;        {&lt;br /&gt;            //server &amp;amp; client 已經連線完成&lt;br /&gt;            while (_TcpClient.Connected)&lt;br /&gt;            {&lt;br /&gt;                //取得網路串流物件，取得來自 socket client 的訊息&lt;br /&gt;                NetworkStream netStream = _TcpClient.GetStream();&lt;br /&gt;                byte[] readBuffer = new byte[1024];&lt;br /&gt;                int count = 0;&lt;br /&gt;                if ((count = netStream.Read(readBuffer, 0, readBuffer.Length)) != 0)&lt;br /&gt;                {&lt;br /&gt;                    string clientRequest = Encoding.UTF8.GetString(readBuffer, 0, count);&lt;br /&gt;                    SocketServer.sMessages.Add(" &amp;gt;&amp;gt; " + "From client(" + _ClientNo + ") =&amp;gt;" + clientRequest);&lt;br /&gt;&lt;br /&gt;                    //正確取得 client requst，再回傳給 client&lt;br /&gt;                    string serverResponse = "Server to clinet(" + _ClientNo + ") =&amp;gt; message: " + clientRequest;&lt;br /&gt;                    byte[] sendBytes = Encoding.UTF8.GetBytes(serverResponse);&lt;br /&gt;                    netStream.Write(sendBytes, 0, sendBytes.Length);&lt;br /&gt;                    netStream.Flush();&lt;br /&gt;                    SocketServer.sMessages.Add(" &amp;gt;&amp;gt; " + serverResponse);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SocketClient.cs&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;using System.Net;&lt;br /&gt;using System.Net.Sockets;&lt;br /&gt;&lt;br /&gt;namespace SocketConn&lt;br /&gt;{&lt;br /&gt;    class SocketClient&lt;br /&gt;    {&lt;br /&gt;        #region private property&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 遠端 socket server IP 位址&lt;br /&gt;        /// &lt;/summary&gt;        private string _RemoteIpAddress;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 遠端 socket server 所監聽的 port number&lt;br /&gt;        /// &lt;/summary&gt;        private int _RemotePortNumber;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// socket client 物件(連接遠端 socket server 用)&lt;br /&gt;        /// &lt;/summary&gt;        private TcpClient _TcpClient;&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region public static property&lt;br /&gt;&lt;br /&gt;        public static List&lt;string&gt; sMessages = new List&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region constructor&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// constructor&lt;br /&gt;        ///&lt;/summary&gt;        /// &lt;param name="inRemoteIpAddr" /&gt;&lt;br /&gt;遠端 socket server IP 位址&lt;br /&gt;        /// &lt;param name="inRemotePortNum" /&gt;&lt;br /&gt;遠端 socket server 所監聽的 port number&lt;br /&gt;        public SocketClient(string inRemoteIpAddr, int inRemotePortNum)&lt;br /&gt;        {&lt;br /&gt;            this._RemoteIpAddress = inRemoteIpAddr;&lt;br /&gt;            this._RemotePortNumber = inRemotePortNum;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        #region public method&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 連線至 socket server&lt;br /&gt;        /// &lt;/summary&gt;        public void Connect()&lt;br /&gt;        {&lt;br /&gt;            //初始化 socket client&lt;br /&gt;            _TcpClient = new TcpClient();&lt;br /&gt;            _TcpClient.Connect(_RemoteIpAddress, _RemotePortNumber);&lt;br /&gt;            sMessages.Add("Client Socket Program - Server Connected ...");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &lt;summary&gt;        /// 傳送訊息至 socker server&lt;br /&gt;        /// &lt;/summary&gt;        /// &lt;param name="inMessage" /&gt;&lt;br /&gt;訊息&lt;br /&gt;        /// &lt;returns&gt;socker server 回傳結果&lt;/returns&gt;&lt;br /&gt;        public string Send(string inMessage)&lt;br /&gt;        {&lt;br /&gt;            try&lt;br /&gt;            {&lt;br /&gt;                //取得用來傳送訊息至 socket server 的 stream 物件&lt;br /&gt;                NetworkStream serverStream = _TcpClient.GetStream();&lt;br /&gt;&lt;br /&gt;                //將資料轉為 byte[]&lt;br /&gt;                byte[] outStream = System.Text.Encoding.UTF8.GetBytes(inMessage);&lt;br /&gt;&lt;br /&gt;                //將資料寫入 stream object (表示傳送資料至 socket server)&lt;br /&gt;                serverStream.Write(outStream, 0, outStream.Length);&lt;br /&gt;                serverStream.Flush();&lt;br /&gt;&lt;br /&gt;                //讀取 socket server 回傳值並轉為 string&lt;br /&gt;                byte[] inStream = new byte[10025];&lt;br /&gt;                serverStream.Read(inStream, 0, (int)_TcpClient.ReceiveBufferSize);&lt;br /&gt;                string returndata = System.Text.Encoding.UTF8.GetString(inStream);&lt;br /&gt;&lt;br /&gt;                sMessages.Add("Data from Server : " + returndata);&lt;br /&gt;                return returndata;&lt;br /&gt;            }&lt;br /&gt;            catch (Exception exp)&lt;br /&gt;            {&lt;br /&gt;                sMessages.Add(exp.ToString());&lt;br /&gt;                return exp.ToString();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        #endregion&lt;br /&gt;    }&lt;br /&gt;}&lt;/string&gt;&lt;/string&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2372478792922250860?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2372478792922250860/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2372478792922250860' title='3 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2372478792922250860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2372478792922250860'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2010/03/c-socket-programming.html' title='[C#] Socket Programming'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4828001469573174261</id><published>2009-10-18T16:45:00.002+08:00</published><updated>2009-10-18T16:46:41.262+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Assembly'/><title type='text'>[NASM] BIOS 啟動程序</title><content type='html'>&lt;div&gt;當電腦的電源開啟後，處理器會進入 reset 狀態，此時：&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;所有記憶體的內容會變為 0&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;CS 的值會被預設為 &lt;b&gt;&lt;font class="Apple-style-span" color="#0000FF"&gt;0FFFF[0]H&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;IP(Instruction Pointer) 儲存指令的 offset，預設為 0&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;結合 2 &amp;amp; 3(Code Segment + Offset)，可以知道第一個要執行的指令的 memory address 為 &lt;b&gt;&lt;font class="Apple-style-span" color="#0000FF"&gt;0FFFF0H&lt;/font&gt;&lt;/b&gt;(&lt;b&gt;&lt;font class="Apple-style-span" color="#FF0000"&gt;CS:IP&lt;/font&gt;&lt;/b&gt;)，而這個 memory address 即為 BIOS 的進入點。&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div&gt;BIOS 的常式位於 0FFF0H，他檢查各個 I/O port，並對於存在的設備進行初始化，接著 BIOS 會建立兩個資料區：&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Interrupt Vector Table (中斷向量表)&lt;/b&gt;&lt;br&gt;長度為 1 KB，用來做為當 interrupt(中斷) 發生時，BIOS &amp;amp; OS 用來選擇相對應的 interrupt handler 之用，詳細資料可參考&lt;a id="cfg1" href="http://support.microsoft.com/kb/71486/en-us/" target="_blank" title="此篇文章"&gt;此篇文章&lt;/a&gt;。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;BIOS 資料區&lt;/b&gt;&lt;br&gt;起始位址為 &lt;b&gt;&lt;font class="Apple-style-span" color="#0000FF"&gt;40[0]H&lt;/font&gt;&lt;/b&gt;，大小依據設備的多寡而不同。&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;接著 BIOS 會檢查系統磁碟是否存在，並從系統磁碟下載啟動程式，啟動程式接著從系統磁碟將系統檔案載入 memory，並將控制權交給 OS。&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4828001469573174261?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4828001469573174261/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4828001469573174261' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4828001469573174261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4828001469573174261'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/10/nasm-bios.html' title='[NASM] BIOS 啟動程序'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3798858422935261948</id><published>2009-10-09T08:34:00.002+08:00</published><updated>2009-10-09T08:35:26.045+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='自動化'/><title type='text'>[自動化] 序列埠模擬器(Virtual Serial Port Emulator)</title><content type='html'>最近開發工作由於沒有實體的設備可以接.....因此要想辦法進行模擬...&lt;br /&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;而模擬的設備又是走序列埠(serial port)，因此只好去找找有沒有免費的模擬器可以用...&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;上 Google 搜尋「&lt;b&gt;free serial port emulator&lt;/b&gt;」&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;果然給我找到一套免費的可以用 =&amp;gt;&amp;nbsp;&lt;a id="ix7y" href="http://www.softpedia.com/get/System/System-Miscellaneous/Free-Virtual-Serial-Ports-Emulator.shtml" target="_blank" title="Free Virtual Serial Ports Emulator"&gt;Free Virtual Serial Ports Emulator&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;目前的版本是 0.936.4.687，希望這好東西可以持續的推陳出新囉!&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;我使用的情境如下：&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;建立的 Device Type 為 pair (假設為 COM2 + COM3)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Modbus Slave 模擬程式連結 COM2&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;程式向 COM3 進行 pooling&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;這樣就很完美的連結起來啦!&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;PS. 這套軟體無法作序列埠的相關設定，例如：Baud Rate。是比較可惜的地方，希望未來可以加入這功能囉!&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3798858422935261948?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3798858422935261948/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3798858422935261948' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3798858422935261948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3798858422935261948'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/10/virtual-serial-port-emulator.html' title='[自動化] 序列埠模擬器(Virtual Serial Port Emulator)'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4312108990237559056</id><published>2009-09-20T21:05:00.002+08:00</published><updated>2009-09-20T21:06:41.011+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OS'/><title type='text'>[OS] Computer System Organization</title><content type='html'>&lt;font size="3"&gt;&lt;b&gt;Computer-System Operation&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;現今電腦系統中包含了一個或數個 CPU，以及多個連接在 common bus 上個多個 device controller，每種不同的 device controller 用來處理不同的設備，如下圖所示：&lt;br&gt;&lt;br&gt;&lt;div id="wd7l" style="text-align: left;"&gt;&lt;img style="width: 514px; height: 257px;" src="http://docs.google.com/File?id=ddzmw8vs_78gs933bcm_b"&gt;&lt;/div&gt;&lt;br&gt;CPU 與其他 device controller 可以一起執行，並相互競爭取得 memory cycle；而為了確保不同設備可以依序的存取 shared memory，memory controller 必須提供不同設備同步存取記憶體的方法。&lt;br&gt;&lt;br&gt;當電腦剛開機時，第一個執行的程式稱為「bootstrap」，而 bootstrap 通常存放在硬體的 firmware 中，目的是用來載入 &amp;amp; 啟動 OS kernel。&lt;br&gt;&lt;br&gt;為了做到上述工作，bootstrap 就必須知道 OS 存放的記憶體位址，才有辦法順利載入執行，而 OS 載入後所執行的第一個 process，一般稱為「&lt;b style="color: rgb(255, 0, 0);"&gt;init&lt;/b&gt;」，並等待其他軟/硬體觸發事件以進行處理。&lt;br&gt;&lt;br&gt;硬體是透過傳遞訊號給 CPU 來觸發 interrupt，而軟體則是透過呼叫 system call 來觸發 interrupt；當 CPU 收到 interrupt 訊號，會執行以下動作：&lt;br&gt;&lt;ol&gt;&lt;li&gt;立即停止目前工作&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;將所要執行的工作傳到特定的位址執行(此位址即為提供執行工作服務的起始位址)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;當工作執行完畢，CPU 則會恢復中斷前的運作&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;下圖展示出 CPU 執行與工作執行的時間軸：&lt;br&gt;&lt;div id="vvb9" style="text-align: left;"&gt;&lt;img style="width: 569px; height: 290px;" src="http://docs.google.com/File?id=ddzmw8vs_79htffzzcj_b"&gt;&lt;/div&gt;&lt;br&gt;Interrupt(中斷) 在電腦架構中是非常重要的一個環節，也許不同的電腦會有不同處理 interrupt 的機制，但總是會有共同的部分，當 CPU 收到 interrupt 的訊號時，就會暫停手邊工作，並將 interrupt 丟給合適的中斷處理程序進行處理。&lt;br&gt;&lt;br&gt;最直接的實作方式是有一個專門的程序(routine)，會針對收到的 interrupt 訊號資訊，將其丟給相對應的中斷處理程序處理。&lt;br&gt;&lt;br&gt;另外一種不需要專門程序處理中斷的方式，則是有一個存放「指向 interrupt routines 的指標(pointer)的表格」，因此 interrupt routine 可以直接透過此 table 儲存的 pointer 進行呼叫，而不需要有個專門的代理程序來處理這個部分。&lt;br&gt;&lt;br&gt;每個不同設備所產生的 interrupt 都會有不同的 interrupt routine 來處理，並會以唯一的設備編號作為索引，而這些資訊都會儲存在記憶體最前面的位址。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="3"&gt;&lt;b&gt;Storage Structure&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;主記憶體是 CPU 唯一可以直接存取的區域，而兩者之間的互動是透過 CPU 呼叫 store &amp;amp; load 兩個指令，將資料在 memory &amp;amp; register(暫存區)。&lt;br&gt;&lt;br&gt;其中 load 的作用是將長度為 1 個 word 的資料從 memory 搬到 register 中；而 store 則是將 1 個 word 的資料從 register 回存到 memory 中。&lt;br&gt;&lt;br&gt;然而，除了基本資料的搬移外，CPU 也是會從 memory 中載入指令以執行不同的工作，其運作步驟如下：&lt;br&gt;&lt;ol&gt;&lt;li&gt;CPU 從 memory 中取得所要執行的指令，並將其存放於 instruction register&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;CPU 會將此指令拆解成相對應的 CPU 指令集並執行&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;最後將執行結果回存至 memory 中&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;然而，記憶體中的資料是沒辦法永久儲存的，只要停止供電後就會消失；因此需要其他儲存媒體來協助進行資料的儲存，最常見的當然就是硬碟機 or 光碟片了! 當然還有最近很夯的 USB 隨身碟(屬於 flash memory)。&lt;br&gt;&lt;br&gt;&lt;font size="3"&gt;&lt;b&gt;&lt;br&gt;I/O Structure&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;OS 中有一大部分是專門處理 I/O 的，原因是因為 I/O 的處理好壞會影響到整體系統的效能 &amp;amp; 穩定度。&lt;br&gt;&lt;br&gt;I/O 動作再 OS 是按照以下步驟進行的：&lt;br&gt;&lt;ol&gt;&lt;li&gt;device driver 會先讀取在 device control 中 register 的資訊&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;接著 device controller 會檢視 register 中的內容，判斷所要執行的動作為何 (例如：從鍵盤讀取一個字元)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;device controller 開始從裝置中讀取資料至本地端的緩衝區&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;資料傳輸完畢，device controller 會發送 interrupt 告知 device driver&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;最後 device driver 會將控制權歸還給 OS&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;若是執行的動作為 read，就會傳取得的資料(or 指向資料所在的位置的 pointer)；但若執行的是其他動作，則會回傳狀態資訊&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;看了上面的動作，若是還搞不懂，可以將整個動作想像成：設備要傳遞資料到記憶體中，必須一直發中斷給 CPU，並將資料傳給 CPU 後，由 CPU 把資料放入記憶體中。&lt;br&gt;&lt;br&gt;顯而易見的，所有資料在傳遞時都必須依賴 CPU 的處理，若是速度很慢的裝置(例如：軟碟機)進行 I/O，就會拖垮整個系統的運作效能。&lt;br&gt;&lt;br&gt;因此，以上的 I/O 動作在處理量少的資料時還可以，但若是處理量大的資料(例如進行 Disk I/O)，就會產生極高的 overhead，而為了解決此問題，就有了 DMA(Direct Memory Access) 的產生，以下有張示意圖：&lt;br&gt;&lt;br&gt;&lt;div id="re:7" style="text-align: left;"&gt;&lt;img style="width: 478px; height: 380px;" src="http://docs.google.com/File?id=ddzmw8vs_80dhmm2pcv_b"&gt;&lt;/div&gt;&lt;br&gt;有了 DMA 之後，device 就可以直接將資料以 block 的方式從本身的緩衝區傳入 memory 中，且不會中斷 CPU 的工作，頂多就是當每個 block 資料傳遞完畢後，發個 interrupt 通知 device driver 動作已經完成。&lt;br&gt;&lt;br&gt;有些更高階的 OS，使用的是 switch 的機制而非 bus 的架構，在這種 OS 中，不同的元件之間不需要在共用的 bus 上搶奪 cycle，且可以同時相互溝通。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="3"&gt;參考資料&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="[文章]DMA - Direct Memory Access 直接記憶體存取 [論壇存檔] - 虛空論壇" target="_blank" href="http://www.helzone.com/vbb/archive/index.php/t-12726.html" id="hgxp"&gt;[文章]DMA - Direct Memory Access 直接記憶體存取 [論壇存檔] - 虛空論壇&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="直接記憶體存取(Direct Memory Access)(1)" target="_blank" href="http://vrschool.ice.cycu.edu.tw/vrschool/Course/OS/%E6%8A%95%E5%BD%B1%E7%89%87/%E4%BD%9C%E6%A5%AD%E7%B3%BB%E7%B5%B1%E7%AC%AC%E4%BA%8C%E7%AB%A0/sld022.htm" id="mfy_"&gt;直接記憶體存取(Direct Memory Access)(1)&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="直接記憶體存取 - 維基百科，自由的百科全書" target="_blank" href="http://zh.wikipedia.org/wiki/%E7%9B%B4%E6%8E%A5%E8%A8%98%E6%86%B6%E9%AB%94%E5%AD%98%E5%8F%96" id="eu3w"&gt;直接記憶體存取 - 維基百科，自由的百科全書&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4312108990237559056?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4312108990237559056/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4312108990237559056' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4312108990237559056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4312108990237559056'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/09/os-computer-system-organization.html' title='[OS] Computer System Organization'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8964561635127282185</id><published>2009-08-19T17:13:00.002+08:00</published><updated>2009-08-19T17:15:36.680+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ] 製作分頁功能 - 使用 skip &amp; take</title><content type='html'>開發網頁程式時，分頁功能總是少不掉的.......&lt;br&gt;&lt;br&gt;然而不使用 skip 與 take 來過濾資料，全部交給 GridView 控制項處理也是可以......&lt;br&gt;&lt;br&gt;以下是使用範例：&lt;br&gt;&lt;br&gt;&lt;b&gt;xxx.aspx&lt;/b&gt;&lt;br&gt;&lt;div id="ofth" style="text-align: left;"&gt;&lt;img style="width: 473px; height: 54px;" src="http://docs.google.com/File?id=ddzmw8vs_68cgfvmhp5_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;b&gt;xxx.aspx.cs&lt;/b&gt;&lt;br&gt;&lt;div id="o6ct" style="text-align: left;"&gt;&lt;img style="width: 578px; height: 407px;" src="http://docs.google.com/File?id=ddzmw8vs_69hjbfhpgz_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;然而若是使用 skip &amp;amp; take，就可以僅取得部份資料，讓分頁相關的程式撰寫上更加有彈性，以下是使用方式：&lt;br&gt;&lt;br&gt;&lt;b&gt;xxx.aspx&lt;/b&gt;&lt;br&gt;&lt;div id="jr.x" style="text-align: left;"&gt;&lt;img style="width: 558px; height: 178px;" src="http://docs.google.com/File?id=ddzmw8vs_70tvrdf8gf_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;b&gt;xxx.aspx.cs&lt;/b&gt;&lt;br&gt;&lt;div id="i2r6" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 586.759px;" src="http://docs.google.com/File?id=ddzmw8vs_71dtxkc2gv_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;b&gt;執行結果&lt;/b&gt;&lt;br&gt;&lt;div id="l::i" style="text-align: left;"&gt;&lt;img style="width: 270px; height: 386px;" src="http://docs.google.com/File?id=ddzmw8vs_72fgkkr2cz_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8964561635127282185?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8964561635127282185/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8964561635127282185' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8964561635127282185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8964561635127282185'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/08/linq-skip-take.html' title='[LINQ] 製作分頁功能 - 使用 skip &amp;amp; take'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-313513777514099365</id><published>2009-08-16T07:25:00.003+08:00</published><updated>2009-08-16T07:39:28.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><title type='text'>[Silverlight 3.0] 如何讓消失的 ASP.NET Silverlight 控制項重新出現</title><content type='html'>昨天安裝了 Silverlight 3.0 的開發環境準備來學習一下 Silverlight&lt;br /&gt;&lt;br /&gt;結果看書上有 ASP.NET Silverlight 控制項，但我的 VS 2010 就硬是不給我出現，解決方式有兩種：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;安裝 Silverlight 2.0 SDK (沒錯......裝了 3.0 SDK 並不會有 2.0 SDK 有的東西....超怪....)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;若不想安裝 2.0 SDK，則可以參考&lt;a href="http://www.limingchstudio.com/2009/07/silverlight-3-sdk-aspnet-mediaplayer.html" target="_blank"&gt;此篇文章&lt;/a&gt;，額外下載並加入 &lt;a href="http://code.msdn.microsoft.com/aspnetprojects" target="_blank"&gt;ASP.NET Server Controls for Silverlight Samples&lt;/a&gt; 即可&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-313513777514099365?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/313513777514099365/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=313513777514099365' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/313513777514099365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/313513777514099365'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/08/silverlight-30-aspnet-silverlight.html' title='[Silverlight 3.0] 如何讓消失的 ASP.NET Silverlight 控制項重新出現'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-404097381090227484</id><published>2009-08-13T17:22:00.008+08:00</published><updated>2009-08-18T11:51:55.387+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ] 常用語法介紹</title><content type='html'>&lt;b&gt;&lt;font size="4"&gt;根據特定條件取得資料 - Where&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;a title="IEnumerable&amp;lt;T&amp;gt;.Where" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb910023.aspx" id="r:ej"&gt;&lt;br&gt;IEnumerable&amp;lt;T&amp;gt;.Where&lt;/a&gt; 可以協助將篩選出我們想要的資訊，共有兩種用法，首先介紹一般 where 的用法：&lt;br&gt;&lt;div id="kmsw" style="text-align: left;"&gt;&lt;img style="width: 316px; height: 134px;" src="http://docs.google.com/File?id=ddzmw8vs_42cfpj3mcp_b"&gt;&lt;/div&gt;&lt;br&gt;接著是另一種較為特別的用法，其中還將資料的 index 也考慮進來：&lt;br&gt;&lt;div id="m40w" style="text-align: left;"&gt;&lt;img style="width: 483px; height: 118px;" src="http://docs.google.com/File?id=ddzmw8vs_43s9nwf4cn_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="4"&gt;取得特定欄位資料 - Select&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;a title="Enumerable.Select" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.select.aspx" id="f4vk"&gt;&lt;br&gt;Enumerable.Select&lt;/a&gt; 用來取得我們所要得資料欄位或是物件，使用上除了可用 LINQ 的語法之外，亦可透過 Extension Method 的特性來使用 Select。&lt;br&gt;&lt;br&gt;首先介紹透過 LINQ 語法來使用 Select：&lt;br&gt;&lt;div id="dj1d" style="text-align: left;"&gt;&lt;img style="width: 564px; height: 406px;" src="http://docs.google.com/File?id=ddzmw8vs_44cn8nx5fw_b"&gt;&lt;/div&gt;&lt;br&gt;接著是使用 Extension Method：&lt;br&gt;&lt;div id="d7sc" style="text-align: left;"&gt;&lt;img style="width: 433px; height: 85px;" src="http://docs.google.com/File?id=ddzmw8vs_45gfdr2ngv_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;此外，LINQ 還提供了一個 &lt;a title="Enumerable.SelectMany" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany.aspx" id="ux2w"&gt;Enumerable.SelectMany&lt;/a&gt; 的語法，可以將取得的集合物件直接展開使用，以下用範例說明：&lt;br&gt;&lt;div id="r01_" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 366.573px;" src="http://docs.google.com/File?id=ddzmw8vs_46gmqr9pdb_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="4"&gt;去除重複 - Distinct&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;與 SQL 語法相同，LINQ 中也提供了 Distinct 來過濾掉重複的資料：&lt;br&gt;&lt;div id="hujo" style="text-align: left;"&gt;&lt;img style="width: 504px; height: 151px;" src="http://docs.google.com/File?id=ddzmw8vs_47794shfcx_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="4"&gt;將 query 後的資料轉為其他集合型態&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;在 LINQ 中提供了 &lt;a title="ToList()" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb342261.aspx" id="x1bj"&gt;ToList()&lt;/a&gt;、&lt;a title="ToArray()" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb298736.aspx" id="rhcy"&gt;ToArray()&lt;/a&gt;、ToDictionary 等方法將 query 後的資料轉為不同的集合型態來使用，但有一點需要注意，.NET 處理的方式是「&lt;b&gt;複製一份資料集合&lt;/b&gt;」。&lt;br&gt;&lt;br&gt;因此，若是 query 得到的資料很龐大，想當然而呼叫 ToList() 或是 ToArray() 這一類的方法就會很耗費系統資源，使用上就必須要注意一下。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="4"&gt;聚合函數(Arregation Functions)&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;LINQ 中也提供了許多聚合函數，例如：Max、Min、Sum、Count ... 等等，以下介紹使用方式：&lt;br&gt;&lt;div id="h598" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 246.435px;" src="http://docs.google.com/File?id=ddzmw8vs_48g722zfgr_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;div&gt;&lt;b&gt;&lt;font size="4"&gt;排序(Sorting)&lt;/font&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;根據條件取得資料後，也許還會有排序的需求，當然 LINQ 也提供了排序的語法 &lt;a id="uebc" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderby.aspx" target="_blank" title="Enumerable.OrderBy"&gt;Enumerable.OrderBy&lt;/a&gt;，以下介紹其使用方式：&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;img style="width: 486px; height: 166px;" src="http://docs.google.com/File?id=ddzmw8vs_49fs7cdmc4_b"&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;從上面的 orderby 使用方式可以發現，可以同時進行不同欄位資料的排序，而這一段 query，.NET Framework 是怎麼幫我們達成的呢?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;其實是將這一段語法拆成三段語法而成的：&lt;/div&gt;&lt;div&gt;&lt;div id="r755" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 160.789px;" src="http://docs.google.com/File?id=ddzmw8vs_50fxhv8zg8_b"&gt;&lt;/div&gt;&lt;br&gt;LINQ 在語法上的使用彈性可見一班!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;巢狀搜尋(Nested Query)&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;從上面的範例到至今，我們都是以 Book 為主的搜尋，根據不同的條件取得不同的資料。&lt;br&gt;&lt;br&gt;假設我們要改以 Publisher 為主來搜尋呢? 假設要搜尋的資料是不同的 Publisher 所出版的書籍清單，這該怎麼作呢?&lt;br&gt;&lt;br&gt;由於每個 Publisher 出版的書籍數量不一定是僅有一本，因此搜尋出來的資料就肯定無法用 row by row 的方式來呈現；而是必須取得 Publisher 清單後，再根據每個 Publisher 取得相對應的出版書籍。&lt;br&gt;&lt;br&gt;因此我們可以將目標設定在取得類似以下資料：&lt;br&gt;&lt;ul&gt;&lt;li&gt;Publisher(出版商) -&amp;gt; Books(出版書籍清單)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Publisher(出版商) -&amp;gt; Books(出版書籍清單)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;..... (etc)&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;可以用以下語法達成：&lt;br&gt;&lt;div id="r3vq" style="text-align: left;"&gt;&lt;img style="width: 463px; height: 183px;" src="http://docs.google.com/File?id=ddzmw8vs_51cb7dk7f7_b"&gt;&lt;/div&gt;&lt;br&gt;當然 aspx 中也要有相對應的 GridView 設定：&lt;br&gt;&lt;div id="gy2q" style="text-align: left;"&gt;&lt;img style="width: 565px; height: 194px;" src="http://docs.google.com/File?id=ddzmw8vs_52fr739qhm_b"&gt;&lt;/div&gt;&lt;br&gt;執行結果如下：&lt;br&gt;&lt;div id="y3tw" style="text-align: left;"&gt;&lt;img style="width: 362px; height: 222px;" src="http://docs.google.com/File?id=ddzmw8vs_53drhpczhh_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;群組(Grouping)&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;以上面為例，若是要達到相同效果，也可以改用 Group 的方式，而且透過 Group 的方式取得資料，沒有出版書的 Publisher 就不會出現囉!&lt;br&gt;&lt;div id="tcq2" style="text-align: left;"&gt;&lt;img style="width: 423px; height: 325px;" src="http://docs.google.com/File?id=ddzmw8vs_54ddb76pfk_b"&gt;&lt;/div&gt;&lt;br&gt;aspx 的部分就跟 Nested Query 中的相同!&lt;br&gt;&lt;br&gt;執行結果如下：&lt;br&gt;&lt;div id="r980" style="text-align: left;"&gt;&lt;img style="width: 362px; height: 401px;" src="http://docs.google.com/File?id=ddzmw8vs_55f239hqf5_b"&gt;&lt;/div&gt;&lt;br&gt;仔細觀察程式碼，其中的 PublisherBooks 為 LINQ 處理後所會回傳的群組資料(根據 book.Publisher 分群)，而 PublisherBooks 則會預設實作 &lt;a title="IGrouping" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb344977.aspx" id="vyuh"&gt;IGrouping&lt;/a&gt; 介面。&lt;br&gt;&lt;br&gt;實作 &lt;a title="IGrouping" target="_blank" href="http://msdn.microsoft.com/en-us/library/bb344977.aspx" id="xcdz"&gt;IGrouping&lt;/a&gt; 介面即表示這群資料集合中，都擁有相同的 key 值，也就是作為分群條件的 book.Publisher。&lt;br&gt;&lt;br&gt;跟 Nested query 相比較，使用 Group 的方式取得資料至少有兩樣優點：&lt;br&gt;&lt;ol&gt;&lt;li&gt;查詢語法更加精簡&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;可在查詢語法中對群組命名，以便後續使用(例如：與 aggregation function 進行搭配使用)&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;Joins&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;既然 LINQ 是針對資料集合進行處理，那怎麼會少掉 Join 這個強大的語法呢? &lt;br&gt;&lt;br&gt;以下用 Join 語法來達到上面範例分群組的功能：&lt;br&gt;&lt;div id="i_lj" style="text-align: left;"&gt;&lt;img style="width: 615px; height: 198px;" src="http://docs.google.com/File?id=ddzmw8vs_56cjdb5vk8_b"&gt;&lt;/div&gt;&lt;br&gt;aspx 的部分也是跟先前的範例相同!&lt;br&gt;&lt;br&gt;執行結果如下：&lt;br&gt;&lt;div id="mb4." style="text-align: left;"&gt;&lt;img style="width: 364px; height: 220px;" src="http://docs.google.com/File?id=ddzmw8vs_57f8fj3hhq_b"&gt;&lt;/div&gt;&lt;br&gt;而從這範例結果可以看出，沒有出版書籍的 Publisher 也會一並被列出(跟 Nested Query 的結果相同)，而若是要避開這種情況，可以改用其他 Join 的方式。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Inner Join&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;這是一般最常用的 join 方式，會過濾掉沒有符合資料的紀錄，以下是使用方式：&lt;br&gt;&lt;div id="o654" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 173.622px;" src="http://docs.google.com/File?id=ddzmw8vs_58hsb6mcfw_b"&gt;&lt;/div&gt;&lt;br&gt;執行結果如下：&lt;br&gt;&lt;div id="xhf1" style="text-align: left;"&gt;&lt;img style="width: 320px; height: 143px;" src="http://docs.google.com/File?id=ddzmw8vs_59r8z27cf3_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Left Outer Join&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;若是要留下 join 中沒有比對符合資料的紀錄，就必須改用 Left(Right) Outer Join 了，但 LINQ 中並沒有提供語法可以直接作到，因此要搭配 DefaultIfEmpty 方法來達到此效果：&lt;br&gt;&lt;div id="f1ik" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 203.533px;" src="http://docs.google.com/File?id=ddzmw8vs_63vq7qvfgm_b"&gt;&lt;/div&gt;&lt;br&gt;執行結果如下：&lt;br&gt;&lt;div id="n93a" style="text-align: left;"&gt;&lt;img style="width: 322px; height: 167px;" src="http://docs.google.com/File?id=ddzmw8vs_61frq3x9hf_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Cross Join&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;這個就是有名的 Cartesian Product(卡氏積)，會將 Join 兩方所有可能的組合通通列出，在 LINQ 中要達到這樣的效果，可以用下列的方式：&lt;br&gt;&lt;div id="pdez" style="text-align: left;"&gt;&lt;img style="width: 470px; height: 213px;" src="http://docs.google.com/File?id=ddzmw8vs_62g7t3nzds_b"&gt;&lt;/div&gt;&lt;br&gt;以下是程式執行結果：&lt;br&gt;&lt;div id="ygbk" style="text-align: left;"&gt;&lt;img style="width: 381px; height: 361px;" src="http://docs.google.com/File?id=ddzmw8vs_41ckmwc6dd_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-404097381090227484?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/404097381090227484/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=404097381090227484' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/404097381090227484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/404097381090227484'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/08/linq.html' title='[LINQ] 常用語法介紹'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3793393472590744769</id><published>2009-07-04T15:41:00.002+08:00</published><updated>2009-07-04T15:42:38.283+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>[JavaScript] 將JavaScript 物件轉為 json 字串</title><content type='html'>一般將物件轉為 json 字串都是在編譯式的程式語言中進行的! 而這次有需要宣告 JavaScript 物件並轉為 json 字串。&lt;br&gt;&lt;br&gt;Google 了一下，發現已經有人提供寫好的 &lt;a title="JavaScript Library" target="_blank" href="http://www.json.org/js.html" id="mvk9"&gt;JavaScript Library&lt;/a&gt; 可以用啦!&lt;br&gt;&lt;br&gt;以下有一段語法，包含 JavaScript 物件的宣告並搭配 jQuery 一同使用此 library：&lt;br&gt;&lt;br&gt;&lt;div id="conh" style="text-align: left;"&gt;&lt;img style="width: 619px; height: 326px;" src="http://docs.google.com/File?id=ddzmw8vs_26hhmjz8c2_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="JSON in JavaScript" target="_blank" href="http://www.json.org/js.html" id="y5mh"&gt;JSON in JavaScript&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="JSON Encoder/Decoder Functions For JavaScript" target="_blank" href="http://www.openjs.com/scripts/data/json_encode.php" id="gu8j"&gt;JSON Encoder/Decoder Functions For JavaScript&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3793393472590744769?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3793393472590744769/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3793393472590744769' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3793393472590744769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3793393472590744769'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/07/javascript-javascript-json.html' title='[JavaScript] 將JavaScript 物件轉為 json 字串'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4333638675098458398</id><published>2009-07-04T15:21:00.002+08:00</published><updated>2009-07-04T15:23:19.969+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>[jQuery] 引用外部 JS 檔</title><content type='html'>在使用 jQuery 時，有時會需要額外引用外部的 js 檔案來使用裡面的功能&lt;br&gt;&lt;br&gt;要怎麼作呢?&lt;br&gt;&lt;br&gt;以下有一段範例語法：&lt;br&gt;&lt;div id="wvff" style="text-align: left;"&gt;&lt;img style="width: 624px; height: 146px;" src="http://docs.google.com/File?id=ddzmw8vs_24dbkbfvsf_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="javascript include javascript(使用jQuery) - cloudio™- 點部落" target="_blank" href="http://www.dotblogs.com.tw/cloudio/archive/2008/08/21/4960.aspx" id="obwm"&gt;javascript include javascript(使用jQuery) - cloudio™- 點部落&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4333638675098458398?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4333638675098458398/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4333638675098458398' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4333638675098458398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4333638675098458398'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/07/jquery-js.html' title='[jQuery] 引用外部 JS 檔'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6199151379192206857</id><published>2009-06-25T10:47:00.002+08:00</published><updated>2009-06-25T10:49:25.664+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><title type='text'>發神經的 VS.NET 2008</title><content type='html'>平常用 3.0 以後提供的語法 &amp;amp; 功能習慣了.....例如：&lt;br&gt;&lt;blockquote&gt;public string test { get; set; }&lt;br&gt;&lt;br&gt;var myVar = "text";&lt;br&gt;&lt;br&gt;var newObject = new MyObject { Name = "myobject", Age = 12; }&lt;br&gt;&lt;/blockquote&gt;大概就以上這些語法.......&lt;br&gt;&lt;br&gt;今天用 VS.NET 2008 開啟後，重新編譯卻發現這些語法都死光光了.....例如出現以下訊息：&lt;br&gt;&lt;blockquote&gt;'xxxxxxx' 不是標記成 abstract 或 extern，因此必須宣告主體&lt;br&gt;&lt;/blockquote&gt;上面就是因為用了第一段程式碼的第一行語法所出現的錯誤.....(但這是 2.0 才會出現的...)&lt;br&gt;&lt;br&gt;看到這情況真是莫名其妙，於是再專案"屬性頁"中，在"建置"中的目標 Framework 中選擇 ".NET Framework 3.0" 編譯一次(當然會錯誤)，再改回 ".NET Framework 3.5" 編譯一次就正常了....&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6199151379192206857?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6199151379192206857/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6199151379192206857' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6199151379192206857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6199151379192206857'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/vsnet-2008.html' title='發神經的 VS.NET 2008'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7576660967412790656</id><published>2009-06-23T16:09:00.002+08:00</published><updated>2009-06-23T16:10:54.749+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] 項目控制項</title><content type='html'>&lt;div&gt;&lt;font size="4"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;由於項目控制項繼承自 &lt;a title="System.Windows.Controls.ItemsControl" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.aspx" id="mlpe"&gt;System.Windows.Controls.ItemsControl&lt;/a&gt; 類別，因此可以容納整個集合的物件，不限定單一物件，而且每個項目都可以是任何物件。(UIElement 會呈現出來，非 UIElement 則是顯示 ToString() 的結果)&lt;br&gt;&lt;br&gt;ItemsControl 有幾個屬性必須要了解：&lt;br&gt;&lt;ol&gt;&lt;li&gt;&lt;a title="HasItems" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.hasitems.aspx" id="w:sw"&gt;HasItems&lt;/a&gt;：用來檢查集合中有沒有內容&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="IsGrouping" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.isgrouping.aspx" id="q5p:"&gt;IsGrouping&lt;/a&gt;：用來辨識集合中的項目是否有分群&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="DisplayMemberPath" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.displaymemberpath.aspx" id="oexv"&gt;DisplayMemberPath&lt;/a&gt;：使用項目物件中的屬性來顯示(也可以是運算式喔!)&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;而項目控制項大致可分為以下三類：&lt;br&gt;&lt;ol&gt;&lt;li&gt;選取器&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;功能表&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;其他項目控制項&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;選取器&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;選取器的特色在於可用 index 的方式存取，並且可以選取。&lt;br&gt;&lt;br&gt;因此選取器繼承 ItemsControl 之後，額外加入了處理選取功能的屬性，例如 SelectedIndex、SelectedItem、SelectedValue .... 等等都是。&lt;br&gt;&lt;br&gt;而 WPF 中提供了四個選取器控制項，分別是 &lt;a title="ComboBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox.isdropdownopen.aspx" id="a7t1"&gt;ComboBox&lt;/a&gt;、&lt;a title="ListBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.aspx" id="ux1c"&gt;ListBox&lt;/a&gt;、ListView、TabControl。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;ComboBox&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="ComboBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox.isdropdownopen.aspx" id="s-dv"&gt;ComboBox&lt;/a&gt; 中定義了屬性 &lt;a title="IsDropDown" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox.isdropdownopen.aspx" id="fxfs"&gt;IsDropDown&lt;/a&gt; 可判斷目前下拉式選單的狀態是展開或是收合；另外還定義了兩個事件，分別是 &lt;a title="OnDropDownOpened" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox.ondropdownopened.aspx" id="a.yr"&gt;OnDropDownOpened&lt;/a&gt; 以及 &lt;a title="OnDropDownClosed" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.combobox.ondropdownclosed.aspx" id="ed9y"&gt;OnDropDownClosed&lt;/a&gt;，可在有特殊需求時填入相對應的程式碼。&lt;br&gt;&lt;/div&gt;&lt;br&gt;以下為範例：&lt;br&gt;(&lt;b&gt;IsEditable = false&lt;/b&gt;)&lt;div id="f8hl" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 482.951px;" src="http://docs.google.com/File?id=ddzmw8vs_9fj2bdzdw_b"&gt;&lt;/div&gt;&lt;div id="l262" style="text-align: left;"&gt;&lt;img style="width: 400px; height: 400px;" src="http://docs.google.com/File?id=ddzmw8vs_11jjbv9mj6_b"&gt;&lt;/div&gt;&lt;br&gt;(&lt;b&gt;IsEditable = true&lt;/b&gt;)&lt;div id="jevn" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 481.534px;" src="http://docs.google.com/File?id=ddzmw8vs_8g6z898hk_b"&gt;&lt;/div&gt;&lt;div id="g_m9" style="text-align: left;"&gt;&lt;img style="width: 400px; height: 400px;" src="http://docs.google.com/File?id=ddzmw8vs_10hhprtsd5_b"&gt;&lt;/div&gt;&lt;br&gt;若是要更清晰的表達每個項目，可使用 &lt;b style="color: rgb(255, 0, 0);"&gt;ComBoxItem&lt;/b&gt; 標籤包住每一個項目內容，如此一來，不只清楚，還可以在 ComboBoxItem 標籤上加上 IsSelected 或是 IsHightlighted 等屬性。&lt;br&gt;&lt;br&gt;但若使用 ComboBoxItem，TextSearch.Text 屬性就無法設定在上面範例的 StackPanel 上，而是要設定在 ComboBoxItem 上囉!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="3"&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;ListBox&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;基本上 &lt;a title="ListBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.aspx" id="hi6p"&gt;ListBox&lt;/a&gt; 跟 ComboBox 是很相似的，只是 ListBox 一次顯示所有項目而已，且有三種不同的選取模式：&lt;br&gt;&lt;ol&gt;&lt;li&gt;Single (預設)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Multiple&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Extended：搭配 Shift/Ctrl 進行多選&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;而 ComboBox 有 ComboBoxItem 標籤，ListBox 也有 ListBoxItem 標籤可以使用囉!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;ListView&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;ListView 繼承自 ListBox，額外增加了 View 的屬性，可以讓開發者自訂更豐富的顯示方式，以下示範使用方式：&lt;div id="hfxw" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 387.31px;" src="http://docs.google.com/File?id=ddzmw8vs_6hqm822nw_b"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="fx0r" style="text-align: left;"&gt;&lt;img style="width: 200px; height: 200px;" src="http://docs.google.com/File?id=ddzmw8vs_7d929tbg5_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;TabControl&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;TabControl 是很基本的控制項，以下為示範：&lt;div id="xql-" style="text-align: left;"&gt;&lt;img style="width: 532px; height: 193px;" src="http://docs.google.com/File?id=ddzmw8vs_4g7mz2p2q_b"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="qcm1" style="text-align: left;"&gt;&lt;img style="width: 300px; height: 300px;" src="http://docs.google.com/File?id=ddzmw8vs_5cx9ftpd5_b"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;功能表&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;這部分有 &lt;a title="Menu" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.menu.aspx" id="u3r4"&gt;Menu&lt;/a&gt; 以及 &lt;a title="ContextMenu" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contextmenu.aspx" id="y4q:"&gt;ContextMenu&lt;/a&gt; 兩個控制項，使用起來的效果與原本 2.0 中其實是差不多的，可以參考以下範例：&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="WPF學習日誌 ~Menu~ - MakeIT II- 點部落" target="_blank" href="http://www.dotblogs.com.tw/bauann/archive/2008/04/11/2869.aspx" id="kzhp"&gt;WPF學習日誌 ~Menu~ - MakeIT II- 點部落&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="WPF學習日誌 ~ ContextMenu ~ - MakeIT II- 點部落" target="_blank" href="http://www.dotblogs.com.tw/bauann/archive/2008/04/12/2876.aspx" id="fic4"&gt;WPF學習日誌 ~ ContextMenu ~ - MakeIT II- 點部落&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;font size="4"&gt;其他項目控制項&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;此部分包含了 TreeView、ToolBar、StatusBar 等等。&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;TreeView&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;以下是 TreeView 控制項的使用範例：&lt;div id="clf_" style="text-align: left;"&gt;&lt;img style="width: 607px; height: 356px;" src="http://docs.google.com/File?id=ddzmw8vs_12d8pzktdc_b"&gt;&lt;/div&gt;&lt;br&gt;另外還有查到 &lt;a title="TreeView 的使用範例教學" target="_blank" href="http://www.c-sharpcorner.com/UploadFile/mahesh/WPFTreeView08202008231544PM/WPFTreeView.aspx" id="gyes"&gt;TreeView 的使用範例教學&lt;/a&gt;，可以參考看看!&lt;br&gt;&lt;br&gt;而 TreeViewItem 較為常用的屬性有 IsExpanded、IsSelected 兩個屬性，以及 Expanded、Collapsed、Selected、Unselected 這幾個事件囉!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;ToolBar&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;可以把 &lt;a title="ToolBar" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms750566.aspx" id="vo2-"&gt;ToolBar&lt;/a&gt; 想像是功能表的加強版! 可以將許多按鈕群組在一起。&lt;br&gt;&lt;br&gt;以下找到一個簡單的使用範例教學：&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="MakeIT: WPF學習日誌 ~ ToolBar ~" target="_blank" href="http://bauann-makeit.blogspot.com/2008/04/wpf-toolbar.html" id="j7lq"&gt;MakeIT: WPF學習日誌 ~ ToolBar ~&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;StatusBar&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="StatusBar" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.statusbar.aspx" id="sxwi"&gt;StatusBar&lt;/a&gt; 也像是功能表，但其項目是以水平堆疊而成的，上網找到幾個不錯的相關教學：&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Kent Boogaart: The Perfect WPF StatusBar" target="_blank" href="http://kentb.blogspot.com/2007/10/perfect-wpf-statusbar.html" id="j1tf"&gt;Kent Boogaart: The Perfect WPF StatusBar&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="MSDN2 - StatusBar Sample" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms771396.aspx" id="ny-f"&gt;MSDN2 - StatusBar Sample&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7576660967412790656?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7576660967412790656/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7576660967412790656' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7576660967412790656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7576660967412790656'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/wpf_23.html' title='[WPF] 項目控制項'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8601516087305451053</id><published>2009-06-19T13:08:00.004+08:00</published><updated>2009-06-19T13:25:13.082+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] 內容控制項</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;內容控制項的 Content 僅能放入一個物件，皆繼承自 &lt;a title="System.Windows.Controls.ContentControl" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx" id="bo_k"&gt;System.Windows.Controls.ContentControl&lt;/a&gt; 類別，而 Content 中的物件可以是任何型別，放入的 element tree 有多大皆可! 但僅能有一個直接的 child element。&lt;br&gt;&lt;br&gt;ContentControl 中有個 HasContent 屬性，有此屬性的定義，就可以透過屬性觸發程序很輕易的在 HasContent 屬性改變時進行其他屬性的設定動作。&lt;br&gt;(上面這一招在 WPF 中使用很多.............)&lt;br&gt;&lt;br&gt;內容控制項分為三大類：&lt;br&gt;&lt;ol&gt;&lt;li&gt;按鈕&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;簡單容器&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;有標題的容器&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;按鈕&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;在 WPF 中，按鈕繼承自 &lt;a title="System.Windows.Controls.Primitives.ButtonBase" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.buttonbase.aspx" id="r0rc"&gt;System.Windows.Controls.Primitives.ButtonBase&lt;/a&gt; 類別，其中以下幾個控制項都繼承自 ButtonBase：&lt;br&gt;&lt;ol&gt;&lt;li&gt;&lt;a title="Button" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms752065%28VS.85%29.aspx" id="ddhn"&gt;Button&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="RepeatButton" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms746715%28VS.85%29.aspx" id="t:.f"&gt;RepeatButton&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="ToggleButton" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.togglebutton.aspx" id="b4wo"&gt;ToggleButton&lt;br&gt;&lt;br&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="CheckBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms754024%28VS.85%29.aspx" id="j_7l"&gt;CheckBox&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="RadioButton" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms748363%28VS.85%29.aspx" id="ru7y"&gt;RadioButton&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Button&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;WPF 中的 Button 類別只有在 ButtonBase 上增加了「取消按鈕」以及「預設按鈕」兩個機制，這兩個機制在對話方塊中很有用：&lt;br&gt;&lt;ol&gt;&lt;li&gt;當 Button.IsCancel = true，此按鈕屬於取消按鈕，點選之後會關閉按鈕所屬的視窗並設定 DialogResult = false。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;當 Button.IsDefault = true，此按扭屬於預設按鈕，當按鈕取得焦點時，按下 Enter 就等於按下此按鈕。&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;RepeatButton&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;RepeatButton 按著不放會持續觸發 Click 事件，但由於直接繼承 ButtonBase 類別，因此沒有取消以及預設兩種機制存在。&lt;br&gt;&lt;br&gt;而 RepeatButton 持續觸發 Click 事件的頻率取決於 &lt;a title="Delay" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.repeatbutton.delay%28VS.95%29.aspx" id="x9q0"&gt;Delay&lt;/a&gt; 以及 &lt;a title="Interval" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.repeatbutton.interval%28VS.95%29.aspx" id="w6f0"&gt;Interval&lt;/a&gt; 兩個屬性，預設即為 &lt;a title="SystemParameters.KeyboardDelay" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.systemparameters.keyboarddelay.aspx" id="u_6z"&gt;SystemParameters.KeyboardDelay&lt;/a&gt; 以及 &lt;a title="SystemParameters.KeyboardSpeed" target="_blank" href="http://SystemParameters.KeyboardSpeed" id="a9o4"&gt;SystemParameters.KeyboardSpeed&lt;/a&gt;。&lt;br&gt;&lt;br&gt;看到以上描述有想起什麼嗎? 沒錯! 就是&lt;a title="之前提過的 DependencyProperty(相依屬性)" target="_blank" href="http://godleon.blogspot.com/2009/04/wpf-dependency-property.html" id="vdzc"&gt;之前提過的 DependencyProperty(相依屬性)&lt;/a&gt; 啊~&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;ToggleButton&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;ToggleButton 可視為「會粘住」的按鈕，因此點選以後會保持狀態，第一次點選 IsChecked = true，再一次點選 IsChecked = false。&lt;br&gt;&lt;br&gt;若 &lt;a title="IsThreeState" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.togglebutton.isthreestate.aspx" id="kvoi"&gt;IsThreeState&lt;/a&gt; 屬性為 true，則 IsChecked 的值的變化為 true -&amp;gt; null -&amp;gt; false，對應到事件的觸發則是：&lt;br&gt;&lt;ul&gt;&lt;li&gt;IsChecked = true 觸發 Checked 事件&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;IsChecked = false 觸發 Unchecked 事件&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;IsChecked = null 觸發 Indeterminate 事件&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;br&gt;&lt;font size="3"&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;CheckBox&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;CheckBox 的特性相當類似於 ToggleButton，因此他是繼承自 ToggleButton 而來的，只是外觀有點不同罷了!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;RadioButton&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;RadioButton 也是繼承自 ToggleButton，另外還支援了單選功能(同一群組內)。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;簡單容器&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Label&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;在 WPF 中的容器控制項，幾乎都可以擺入任意型態的物件，但唯讀 &lt;a title="Label" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.label.aspx" id="nzp7"&gt;Label&lt;/a&gt; 僅能放入文字內容。&lt;br&gt;&lt;br&gt;但雖然如此，Label 控制項卻可以搭配 Alt 進行快捷鍵的設定喔!&lt;br&gt;&lt;br&gt;以下程式會在按下 Alt + U 時，焦點會自動跳到 TextBox 上：&lt;br&gt;&lt;img src="http://lh5.ggpht.com/_-MI_81GSZ2I/Sjsgg2YaukI/AAAAAAAABsY/_0MJT_3PZak/s800/WPF_Label_Code.PNG" /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;ToolTip&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="ToolTip" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.tooltip.aspx" id="axy3"&gt;ToolTip&lt;/a&gt; 是用來顯示提示訊息用，原本都是顯示文字訊息而已，但在 WPF 中，已經可以顯示任何的內容了! 以下有個簡單範例：&lt;br&gt;&lt;img src="http://lh4.ggpht.com/_-MI_81GSZ2I/Sjsgg-cdonI/AAAAAAAABsc/3A8QPDXyD80/s800/WPF_ToolTip_Code.PNG" /&gt;&lt;br&gt;&lt;img src="http://lh6.ggpht.com/_-MI_81GSZ2I/SjscbC3KGrI/AAAAAAAABsM/dRjEvSid-y4/s800/WPF_ToolTip.PNG" /&gt;&lt;br&gt;&lt;br&gt;另外若是要讓 ToolTip 有更多不同的方式進行呈現時(例如：顯示時間長短)，可搭配 &lt;a title="ToolTipService" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.tooltipservice.aspx" id="ecgv"&gt;ToolTipService&lt;/a&gt; 靜態類別來達成!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Frame&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Frame" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.aspx" id="yi4."&gt;Frame&lt;/a&gt; 也可以放入任意內容，且可以同時支援 HTML &amp;amp; WPF，透過設定 &lt;a title="Source" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.frame.source.aspx" id="zdps"&gt;Source&lt;/a&gt; 屬性就可以在 Frame 中顯示連結的內容。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;有標題的容器&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;此部分介紹的控制項(GroupBox、Expander)，由於繼承自 &lt;a title="System.Windows.Controls.HeaderedContentControl" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.headeredcontentcontrol.aspx" id="b3fc"&gt;System.Windows.Controls.HeaderedContentControl&lt;/a&gt; 類別，因此多了一個型態為 Object 的 Header 屬性。而這代表什麼? 代表 Header 可以放進任何你想要放的東西.......&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;GroupBox&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;我們通常將 &lt;a title="GroupBox" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.groupbox.aspx" id="rt3v"&gt;GroupBox&lt;/a&gt; 用將多個控制項歸納為相同群組時使用，但由於它是內容控制項，因此只能有一個 child element，因此我們要用其他的容器來當中介：&lt;br&gt;&lt;img src="http://lh5.ggpht.com/_-MI_81GSZ2I/Sjsgg8aKByI/AAAAAAAABsU/3Hy9wAQYkFQ/s800/WPF_GroupBox_Code.PNG" /&gt;&lt;br&gt;&lt;img src="http://lh4.ggpht.com/_-MI_81GSZ2I/SjscbGgAGLI/AAAAAAAABsI/uj5ANcOGAbM/s800/WPF_GroupBox.PNG" /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;Expander&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Expander" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.expander.aspx" id="zw:t"&gt;Expander&lt;/a&gt; 類似 GroupBox，但有個按鈕可以讓使用者開啟 &amp;amp; 收合所包含的內容：&lt;br&gt;&lt;img src="http://lh3.ggpht.com/_-MI_81GSZ2I/Sjsgg3Uo18I/AAAAAAAABsQ/Kk0Allv8row/s800/WPF_Expander_Code.PNG" /&gt;&lt;br&gt;&lt;img src="http://lh5.ggpht.com/_-MI_81GSZ2I/SjscbL9pYqI/AAAAAAAABsE/wmdOQyvofcs/s800/WPF_Expander.PNG" /&gt;&lt;br&gt;&lt;br&gt;此外，Expander 還定義了 &lt;a title="IsExpanded" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.expander.isexpanded.aspx" id="igzw"&gt;IsExpanded&lt;/a&gt; 屬性以及 &lt;a title="OnExpanded" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.expander.onexpanded.aspx" id="sbjk"&gt;OnExpanded&lt;/a&gt; / &lt;a title="OnCollapsed" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.expander.oncollapsed.aspx" id="qjo2"&gt;OnCollapsed&lt;/a&gt; 兩個事件，還可以透過 &lt;a title="ExpandDirection" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.expander.expanddirection.aspx" id="ldf1"&gt;ExpandDirection&lt;/a&gt; 來控制內容展開的方向。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8601516087305451053?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8601516087305451053/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8601516087305451053' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8601516087305451053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8601516087305451053'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/wpf.html' title='[WPF] 內容控制項'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_-MI_81GSZ2I/Sjsgg2YaukI/AAAAAAAABsY/_0MJT_3PZak/s72-c/WPF_Label_Code.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2254531165331129283</id><published>2009-06-17T17:39:00.003+08:00</published><updated>2009-06-17T17:43:41.610+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ] 初探 LINQ to Objects</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;哪些類別支援 LINQ 相關功能 ?&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;LINQ to Objects 表示要透過 LINQ 與集合型態的物件進行互動，這些資料存在於 memory 中，但是 .NET Framework 提供的類別如此之多，支援 LINQ 存取的是哪些呢?&lt;br&gt;&lt;br&gt;答案就是有實作 &lt;a title="System.Collections.IEnumerable" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.collections.ienumerable%28VS.80%29.aspx" id="e4cq"&gt;System.Collections.IEnumerable&lt;/a&gt; 介面的類別所產生的物件都可以&lt;sub&gt;。&lt;br&gt;&lt;br&gt;&lt;/sub&gt;何以見得? 由於 .NET Framework 3.0 以後加入了 Extension Method(擴充方法) 這個機制，且又在 &lt;a title="System.Linq.Enumerable" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx" id="o2t3"&gt;System.Linq.Enumerable&lt;/a&gt; 類別中針對實作 System.Collections.IEnumerable 介面的類別加入了許多 Extension Method，而這些類別(Array、List、Dictionary .... 等等)則可說是「自動擴充」成擁有 LINQ 的相關功能。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;使用範例&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;首先是 LINQ to Object Array：&lt;br&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        //定義各種不同型態的資料&lt;br /&gt;        Object[] array = { "String", 12, true, 'a' };&lt;br /&gt;&lt;br /&gt;        var types = array.Select(item =&gt; item.GetType().Name)   //選取集合中資料的型態&lt;br /&gt;                         .OrderBy(type =&gt; type);    //根據型態進行排序&lt;br /&gt;&lt;br /&gt;        /* 執行結果：&lt;br /&gt;           Boolean&lt;br /&gt;           Char&lt;br /&gt;           Int32&lt;br /&gt;           String */&lt;br /&gt;        ObjectDumper.Write(types);&lt;br /&gt;        Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;接著是 LINQ to 自行定義的物件(Book) Array：&lt;br&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;using LinqInAction.LinqBooks.Common;&lt;br /&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        Book[] books = { new Book { Title = "LINQ In Action" },&lt;br /&gt;                             new Book { Title = "LINQ For Fun" }, &lt;br /&gt;                             new Book { Title = "Extreme LINQ" } };&lt;br /&gt;&lt;br /&gt;        var titles = books.Where(book =&gt; book.Title.Contains("Action")) //取得 Title 欄位包含 "Action" 關鍵字的書籍資料&lt;br /&gt;                          .Select(book =&gt; book.Title);  //取得 Title 欄位&lt;br /&gt;&lt;br /&gt;        /* 執行結果：&lt;br /&gt;           LINQ In Action */&lt;br /&gt;        ObjectDumper.Write(titles);&lt;br /&gt;        Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;其實，只要是 Array，存放於 Array 中可以是任何型態的物件(因為 Array 有實作 System.Collections.IEnumerable 介面)&lt;br&gt;&lt;br&gt;&lt;br&gt;接著改用 List，除了型態不同以外，query 的方法可說是完全相同：&lt;br&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using LinqInAction.LinqBooks.Common;&lt;br /&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        //即使資料換成是 List，LINQ 的語法也是相同的!&lt;br /&gt;        List&lt;Book&gt; books = new List&lt;Book&gt;() { new Book { Title = "LINQ In Action" },&lt;br /&gt;                                              new Book { Title = "LINQ For Fun" },&lt;br /&gt;                                              new Book { Title = "Extreme LINQ" } };&lt;br /&gt;&lt;br /&gt;        var titles = books.Where(book =&gt; book.Title.Contains("Action")) //取得 Title 欄位包含 "Action" 關鍵字的書籍資料&lt;br /&gt;                          .Select(book =&gt; book.Title);  //取得 Title 欄位&lt;br /&gt;&lt;br /&gt;        /* 執行結果：&lt;br /&gt;           LINQ In Action */&lt;br /&gt;        ObjectDumper.Write(titles);&lt;br /&gt;        Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;這就是 LINQ 想要達成的目標 =&amp;gt; &lt;b&gt;讓 query 的語言一致&lt;/b&gt;! &lt;br&gt;目前嘗試 Array 與 List 的確有這種感覺~&lt;br&gt;&lt;br&gt;&lt;br&gt;最後是 LINQ to Dictionary，並用兩種不同的方式(query operator &amp;amp; query expression)進行查詢：&lt;br&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        Dictionary&lt;int, string&gt; myNumbers = new Dictionary&lt;int,string&gt;();&lt;br /&gt;        myNumbers.Add(0, "zero");&lt;br /&gt;        myNumbers.Add(1, "One");&lt;br /&gt;        myNumbers.Add(2, "Two");&lt;br /&gt;        myNumbers.Add(3, "Three");&lt;br /&gt;        myNumbers.Add(4, "Four");&lt;br /&gt;&lt;br /&gt;        //透過 query operator 的方式取得偶數值&lt;br /&gt;        var evenNumbers01 = myNumbers.Where(number =&gt; number.Key % 2 == 0)&lt;br /&gt;                                   .Select(number =&gt; number.Value);&lt;br /&gt;        ObjectDumper.Write(evenNumbers01);&lt;br /&gt;&lt;br /&gt;        //也可以透過 query expression 的方式取得偶數值&lt;br /&gt;        var evenNumbers02 = from number in myNumbers&lt;br /&gt;                            where (number.Key % 2) == 0&lt;br /&gt;                            select number.Value;&lt;br /&gt;        ObjectDumper.Write(evenNumbers02);&lt;br /&gt;        &lt;br /&gt;        /*&lt;br /&gt;         以上兩個執行結果都會是：&lt;br /&gt;         Zero&lt;br /&gt;         Two&lt;br /&gt;         Four&lt;br /&gt;         */&lt;br /&gt;        Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;由此可見，由於 Extend Method 機制的出現，幾乎讓所有集合型態的資料都可以透過 LINQ 的方式進行存取了，只要有實作 &lt;a title="System.Collections.IEnumerable" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.collections.ienumerable%28VS.80%29.aspx" id="e4cq"&gt;System.Collections.IEnumerable&lt;/a&gt; 介面即可。&lt;br&gt;&lt;br&gt;除此之外，查詢的方式也不僅限於一種，除了 query operator 外也還有 query expression 可以使用，甚至兩種同時搭配使用亦可喔!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2254531165331129283?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2254531165331129283/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2254531165331129283' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2254531165331129283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2254531165331129283'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/linq-linq-to-objects.html' title='[LINQ] 初探 LINQ to Objects'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6385366260345202672</id><published>2009-06-17T09:04:00.002+08:00</published><updated>2010-03-04T16:12:16.939+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><title type='text'>[C#] Deferred Query Execution</title><content type='html'>什麼是 Deferred Query(延遲查詢) Execution 呢? &lt;br&gt;&lt;br&gt;這是在看 &lt;a title="LINQ In Action" target="_blank" href="http://www.amazon.com/LINQ-Action-Fabrice-Marguerie/dp/1933988169/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1245199350&amp;amp;sr=8-1" id="pbll"&gt;LINQ In Action&lt;/a&gt; 的時候發現的，查詢了一下，原來這是 C# 2.0 就已經提供的功能.....&lt;br&gt;&lt;br&gt;用途在於&lt;b style="color: rgb(255, 0, 0);"&gt;可以用更少的資源(Resource)使用集合(collection)物件&lt;/b&gt;!&lt;br&gt;&lt;br&gt;為何這麼說呢? 以下用一段程式碼來說明：&lt;br&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;&lt;br /&gt;namespace DeferredQueryExecution&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static double Square(double n)&lt;br /&gt;        {&lt;br /&gt;            //每呼叫 Square 就會印出下列訊息&lt;br /&gt;            Console.WriteLine("Computing Square(" + n + ")....");&lt;br /&gt;            return Math.Pow(n, 2);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            int[] numbers = { 1, 2, 3 };&lt;br /&gt;&lt;br /&gt;            //取得 numbers 陣列中所有元素的平方值並存入 query 集合物件中&lt;br /&gt;            var query =&lt;br /&gt;                from n in numbers&lt;br /&gt;                select Square(n);&lt;br /&gt;&lt;br /&gt;            //印出 query 集合物件的內容&lt;br /&gt;            foreach (var n in query)&lt;br /&gt;                Console.WriteLine(n);&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;這一段程式碼執行完的結果會是如何呢? 一般來說，應該是以下這樣....&lt;br&gt;&lt;blockquote&gt;Computing Square(1)....&lt;br&gt;Computing Square(2)....&lt;br&gt;Computing Square(3)....&lt;br&gt;1&lt;br&gt;4&lt;br&gt;9&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;但實際跑出來的結果並非這樣，而是：&lt;br&gt;&lt;blockquote&gt;Computing Square(1)....&lt;br&gt;1&lt;br&gt;Computing Square(2)....&lt;br&gt;4&lt;br&gt;Computing Square(3)....&lt;br&gt;9&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;結果令人出乎意料吧! &lt;br&gt;&lt;br&gt;從結果可以看出，.NET compile 在處理集合物件時，並非一次給定完整結果，而是「真的有需要才一個一個慢慢給出」，因此當集合物件的數量龐大時，可以有效降低系統資源的浪費，提升在操作集合物件時的效能。&lt;br&gt;&lt;br&gt;當然，這跟 LINQ 好像沒啥關係......因此只要了解一下 .NET 有這種機制存在即可囉!&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6385366260345202672?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6385366260345202672/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6385366260345202672' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6385366260345202672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6385366260345202672'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/deferred-query-execution.html' title='[C#] Deferred Query Execution'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-9022473955596938261</id><published>2009-06-12T13:10:00.005+08:00</published><updated>2010-03-04T16:12:16.941+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[C#] delegate(委派) -&gt; Lambda Expression -&gt; LINQ</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;觀念解說&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;關於 delegate &amp;amp; Lambda Expression &amp;amp; LINQ 入門，參考以下文章可以得到很清楚的觀念喔!&lt;br&gt;&lt;br&gt;&lt;a title="Huan-Lin 學習筆記: C# 筆記：重訪委派－從 C# 1.0 到 2.0 到 3.0" target="_blank" href="http://huan-lin.blogspot.com/2009/01/delegate-revisited-csharp-1-to-2-to-3.html" id="ci6h"&gt;Huan-Lin 學習筆記: C# 筆記：重訪委派－從 C# 1.0 到 2.0 到 3.0&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Huan-Lin 學習筆記: C# 筆記：從 Lambda 表示式到 LINQ" target="_blank" href="http://huan-lin.blogspot.com/2009/01/from-lambda-to-linq.html" id="po4_"&gt;Huan-Lin 學習筆記: C# 筆記：從 Lambda 表示式到 LINQ&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;a title="C# 3.0 極簡風 - Lambda Expression - 黑暗執行緒" target="_blank" href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/06/13/lambda-expression.aspx" id="lesv"&gt;C# 3.0 極簡風 - Lambda Expression - 黑暗執行緒&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;接著以下只記錄一些瑣碎的筆記........&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;LINQ 從何而來?&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;Lambada Expression 大量了使用了之前所提到的 extension method，而 .NET 中也提供了不少的 extension method 以提昇 Lambada Expression 的易用性，藉此讓 LINQ 的語法更加的直覺!&lt;br&gt;&lt;br&gt;舉例來說，在 &lt;a title="System.Linq.Enumerable" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx" id="dhrk"&gt;System.Linq.Enumerable&lt;/a&gt; class 中，就定義了許多 extension method，例如：&lt;a title="OrderByDescending" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.orderbydescending.aspx" id="hua0"&gt;OrderByDescending&lt;/a&gt;、&lt;a title="Last" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.last.aspx" id="c5ji"&gt;Last&lt;/a&gt;、&lt;a title="Max" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.max.aspx" id="q.2j"&gt;Max&lt;/a&gt;、&lt;a title="Min" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.min.aspx" id="j8bu"&gt;Min&lt;/a&gt;、&lt;a title="Contains" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.contains.aspx" id="t95u"&gt;Contains&lt;/a&gt;、&lt;a title="Count" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.linq.enumerable.count.aspx" id="isw3"&gt;Count&lt;/a&gt;.... 等等。&lt;br&gt;&lt;br&gt;&lt;br&gt;除了 delegate &amp;amp; Lambda Expression 之外，與 LINQ 有關的特殊功能還有 Implicit typed local variables、Object and collection initializers、Anonymous types 等等。&lt;br&gt;&lt;br&gt;而除了 delegate 之外，都是在 C# 3.0 中才有提供的(當然 VB.NET 也有)，因此看得出來，LINQ 可說是集合所有新功能於一身的查詢技術。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;範例說明&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;以上範例將上述的新功能簡單做了一次完整的結合測試：&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Diagnostics;&lt;br /&gt;using System.Linq;&lt;br /&gt;&lt;br /&gt;namespace CompleteCode&lt;br /&gt;{&lt;br /&gt;    //為了將 Extension Method 定義在此類別, 要加上 static 關鍵字&lt;br /&gt;    //否則就要另外定義一個 static class 來放 Extension Method&lt;br /&gt;    static class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            //在呼叫時指定比對用的 function (使用 Lambda Expression)&lt;br /&gt;            DisplayProcesses(process =&gt; process.WorkingSet64 &gt;= 20 * 1024 * 1024);&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //定義 inner class&lt;br /&gt;        class ProcessData&lt;br /&gt;        {&lt;br /&gt;            public Int32 Id { get; set; }&lt;br /&gt;            public Int64 Memory { get; set; }&lt;br /&gt;            public string Name { get; set; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //此處以委派(delegate)的方式將 match 函式交由呼叫端決定&lt;br /&gt;        //傳入的參數型態為 System.Diagnostics.Process&lt;br /&gt;        //回傳型態為 Boolean&lt;br /&gt;        static void DisplayProcesses(Func&lt;Process, Boolean&gt; match)&lt;br /&gt;        {&lt;br /&gt;            //此處變數型態會由 compiler 在編譯時決定&lt;br /&gt;            var processes = new List&lt;ProcessData&gt;();&lt;br /&gt;&lt;br /&gt;            foreach (var process in Process.GetProcesses())&lt;br /&gt;            {&lt;br /&gt;                //使用 Object Initializer 的方式宣告物件並給定值&lt;br /&gt;                if (match(process))&lt;br /&gt;                    processes.Add(new ProcessData { Id = process.Id, Name = process.ProcessName, Memory = process.WorkingSet64 });&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("Total memory: {0} MB", processes.TotalMemory() / 1024 / 1024);&lt;br /&gt;&lt;br /&gt;            //透過 .NET 內建的 Extension Method，取得耗用記憶體最大的兩個 process 所耗費的記憶體總計&lt;br /&gt;            var top2Memory = processes.OrderByDescending(process =&gt; process.Memory)&lt;br /&gt;                                      .Take(2)&lt;br /&gt;                                      .Sum(process =&gt; process.Memory) / 1024 / 1024;&lt;br /&gt;            Console.WriteLine("Memory consumed by the two most processes: {0} MB", top2Memory);&lt;br /&gt;&lt;br /&gt;            //使用 Anonymous Type 宣告物件並顯示&lt;br /&gt;            var results = new { TotalMomery = processes.TotalMemory() / 1024 / 1024,&lt;br /&gt;                                Top2Memory = top2Memory, &lt;br /&gt;                                Processes = processes };&lt;br /&gt;            ObjectDumper.Write(results, 1);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //定義 Extension Method(計算記憶體總使用量)&lt;br /&gt;        //針對 IEnumerable&lt;ProcessData&gt; 型別進行擴充&lt;br /&gt;        static Int64 TotalMemory(this IEnumerable&lt;ProcessData&gt; processes)&lt;br /&gt;        {&lt;br /&gt;            Int64 result = 0;&lt;br /&gt;&lt;br /&gt;            foreach (var process in processes)&lt;br /&gt;                result += process.Memory;&lt;br /&gt;&lt;br /&gt;            return result;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-9022473955596938261?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/9022473955596938261/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=9022473955596938261' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9022473955596938261'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9022473955596938261'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/c-delegate-lambda-expression-linq.html' title='[C#] delegate(委派) -&amp;gt; Lambda Expression -&amp;gt; LINQ'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2576055316798213383</id><published>2009-06-09T17:10:00.017+08:00</published><updated>2011-06-03T15:54:18.823+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><title type='text'>[C#] 3.0 中的新功能 - 擴充方法(Extension Method)</title><content type='html'>&lt;span style="font-size: medium;"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;擴充方法能將方法「加入」至現有型別，但不需要建立新的衍生型別 (Derived Type)、重新編譯，或是修改原始型別。&lt;br&gt;&lt;br&gt;神奇的是，不僅是自訂的型別可以增加 extension method，連既有的型別都可以增加 extension method !&lt;br&gt;&lt;br&gt;隨便舉個例，假設要檢查字串是否為數字，以前都是另外寫個 function 來檢查，例如：&lt;br&gt;&lt;b style="color: blue;"&gt;public bool IsNumeric(string strVal);&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;b style="color: blue;"&gt;&lt;/b&gt;現在若是透過 extension method，只要透過以下方式即可：&lt;br&gt;&lt;b style="color: blue;"&gt;strVal.IsNumeric();&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;b style="color: blue;"&gt;&lt;/b&gt;如何? 使用起來是不是更加直覺了呢?&lt;br&gt;&lt;br&gt;&lt;a href="http://godleon.blogspot.com/2009/06/c-30-extension-method.html#more"&gt;閱讀更多 »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2576055316798213383?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2576055316798213383/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2576055316798213383' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2576055316798213383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2576055316798213383'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/c-30-extension-method.html' title='[C#] 3.0 中的新功能 - 擴充方法(Extension Method)'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-nIc3ZdbXQIU/TeiRMCaTaYI/AAAAAAAAC1c/bJZ8dgJUgkg/s72-c/ExteionMethod_1.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7019559850388170056</id><published>2009-06-09T11:34:00.002+08:00</published><updated>2010-03-04T16:12:16.943+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>[LINQ ] 初探</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;LINQ 是 Microsoft 開發出來專門用來處理集合資訊用的技術，什麼叫做集合資訊呢?&lt;br&gt;&lt;br&gt;舉凡 Database、XML、Object、DataSet、Array、Collection .... 等都可以算是集合資訊&lt;br&gt;&lt;br&gt;而我們再開發軟體時，資料來源也就差不多是上面這些，但每一種資料來源都有很多額外的知識必須要學..... Database 是一門學問、XML 又是一門學問 ...&lt;br&gt;&lt;br&gt;想像一下若是可以用同一套語法來存取以上這些資料來源，不是很迷人的事情嗎?&lt;br&gt;&lt;br&gt;而 LINQ 就是為了這個目的而產生的!&lt;br&gt;&lt;br&gt;瞭解一下 LINQ 的目標就可以知道他有多酷了：(from &lt;a title="LINQ In Action" target="_blank" href="http://www.amazon.com/LINQ-Action-Fabrice-Marguerie/dp/1933988169/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1244184078&amp;amp;sr=8-2" id="b:ht"&gt;LINQ In Action&lt;/a&gt;)&lt;br&gt;&lt;ol&gt;&lt;li&gt;Integrated objects, relational data, and XML (這當然是首要目的)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;SQL and XQuery-like power in C# and VB (整合進 C# &amp;amp; VB.NET 囉)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Extensibility model for languages (提供其他語言的擴充性)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Extensibility model for multiple data sources (當然也提供了不同資料來源的擴充性)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Type safety (透過 compile-time 檢查)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Extensive IntelliSense support (enabled by strong-typing) (這對開發者肯定是一大福音啊!)&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;Debug support (這功能沒有怎麼可以呢?)&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;使用範例&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;首先來個使用範例，LINQ to Object !&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;&lt;br /&gt;namespace HelloLinq&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            //string array&lt;br /&gt;            string[] words = { "hello", "wonderful", "linq", "beautiful", "world" };&lt;br /&gt;&lt;br /&gt;            //取得陣列中字串長度小於等於 5 的字串&lt;br /&gt;            var shortwords = from word in words&lt;br /&gt;                             where word.Length &lt;= 5&lt;br /&gt;                             select word;&lt;br /&gt;            /*  hello&lt;br /&gt;                linq&lt;br /&gt;                world  */&lt;br /&gt;            foreach (var word in shortwords)&lt;br /&gt;                Console.WriteLine(word);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            //依照字串長度分群組&lt;br /&gt;            var groups = from word in words&lt;br /&gt;                         orderby word ascending&lt;br /&gt;                         group word by word.Length into lengthGroups&lt;br /&gt;                         orderby lengthGroups.Key descending&lt;br /&gt;                         select new { Length = lengthGroups.Key, Words = lengthGroups };&lt;br /&gt;            /*&lt;br /&gt;             words of length 9&lt;br /&gt;                 beautiful&lt;br /&gt;                 wonderful&lt;br /&gt;             words of length 5&lt;br /&gt;                 hello&lt;br /&gt;                 world&lt;br /&gt;             words of length 4&lt;br /&gt;                 linq&lt;br /&gt;             */&lt;br /&gt;            foreach (var group in groups)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine("words of length " + group.Length);&lt;br /&gt;                foreach (string word in group.Words)&lt;br /&gt;                    Console.WriteLine("    " + word);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;看到範例的第一個部分，也許有人會覺得沒有 LINQ 也是很好寫吧!&lt;br&gt;&lt;br&gt;但第二部份，不是用 LINQ 的話，可就很費工囉!&lt;br&gt;&lt;br&gt;然而，範例雖然簡單，還是可以看出 LINQ 的語法真的是相當直覺......加上 VS.NET 的 IntelliSense....(難怪 MS 的開發工具這麼多人用.....)&lt;br&gt;&lt;br&gt;&lt;br&gt;接著以下的範例，可以看出 LINQ 如何以幾乎無縫的方式整合進 C#(VB.NET 也行啦) 中，搭配 XML API 來產生 XML 文件：&lt;br&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Xml.Linq;&lt;br /&gt;&lt;br /&gt;namespace HelloLinqToXml&lt;br /&gt;{&lt;br /&gt;    class Book&lt;br /&gt;    {&lt;br /&gt;        public string Publisher;&lt;br /&gt;        public string Title;&lt;br /&gt;        public int Year;&lt;br /&gt;&lt;br /&gt;        public Book(string title, string publisher, int year)&lt;br /&gt;        {&lt;br /&gt;            Title = title;&lt;br /&gt;            Publisher = publisher;&lt;br /&gt;            Year = year;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            //定義 object collection&lt;br /&gt;            Book[] books = new Book[] {&lt;br /&gt;                new Book("Ajax in Action", "Manning", 2005), &lt;br /&gt;                new Book("Windows Forms in Action", "Manning", 2006), &lt;br /&gt;                new Book("RSS and Atom in Action", "Manning", 2006)&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;            //從 object collection 中取得資料後，並搭配 XML API 產生 XML 文件&lt;br /&gt;            XElement xml = new XElement("books", &lt;br /&gt;                from book in books&lt;br /&gt;                where book.Year == 2006&lt;br /&gt;                select new XElement("book", &lt;br /&gt;                    new XAttribute("title", book.Title), &lt;br /&gt;                    new XElement("publisher", book.Publisher)));&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(xml);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;最後一個部分則是 LINQ to SQL，此處以 NorthWind 為範例資料庫：&lt;br&gt;&lt;br /&gt;&lt;pre class="brush:csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Data.Linq;&lt;br /&gt;using System.Data.Linq.Mapping;&lt;br /&gt;using System.Data.SqlClient;&lt;br /&gt;&lt;br /&gt;namespace HelloLinqToSql&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            //設定資料來源&lt;br /&gt;            DataContext db = new DataContext(new SqlConnection("Server=CIC-GODLEON\\SQLEXPRESS;Database=northwind;Trusted_Connection=True;"));&lt;br /&gt;&lt;br /&gt;            //透過 LINQ 來取得資料&lt;br /&gt;            var contacts =&lt;br /&gt;                from contact in db.GetTable&lt;Contact&gt;()&lt;br /&gt;                where contact.City == "Paris"&lt;br /&gt;                select contact;&lt;br /&gt;&lt;br /&gt;            foreach (var contact in contacts)&lt;br /&gt;                Console.WriteLine("Bonjour " + contact.Name);&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    /// &lt;summary&gt;&lt;br /&gt;    /// 必須透過設定 attribute 的方式指定 class 和 DB table 的 mapping&lt;br /&gt;    /// 此處指定對應到 Customers 資料表&lt;br /&gt;    /// &lt;/summary&gt;&lt;br /&gt;    [Table(Name="Customers")]&lt;br /&gt;    class Contact&lt;br /&gt;    {&lt;br /&gt;        /// &lt;summary&gt;&lt;br /&gt;        /// 同樣內部的設定也必須要透過 attribute 的方式設定 mapping&lt;br /&gt;        /// &lt;/summary&gt; &lt;br /&gt;&lt;br /&gt;        //未指定則對應到同名(CustomerID)欄位&lt;br /&gt;        [Column(IsPrimaryKey=true)]&lt;br /&gt;        public string CustomerID { get; set; }&lt;br /&gt;&lt;br /&gt;        //指定對應到 ContactName 欄位&lt;br /&gt;        [Column(Name="ContactName")]&lt;br /&gt;        public string Name { get; set; }&lt;br /&gt;&lt;br /&gt;        //對應 City 欄位&lt;br /&gt;        [Column]&lt;br /&gt;        public string City { get; set; }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="感受到 LINQ 的強大威力了" target="_blank" href="http://blog.miniasp.com/post/2007/11/Feel-the-Power-of-LINQ-to-SQL.aspx" id="w.55"&gt;感受到 LINQ 的強大威力了&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7019559850388170056?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7019559850388170056/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7019559850388170056' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7019559850388170056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7019559850388170056'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/linq_09.html' title='[LINQ ] 初探'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-9222849913970338883</id><published>2009-06-02T15:47:00.003+08:00</published><updated>2009-06-02T16:12:50.808+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>[SQL Server] Alias 的用法</title><content type='html'>今天被問到....&lt;br /&gt;&lt;br /&gt;怎麼用 SQL Server Management Studio 去連 default port number 不是 1433 的 SQL Server..&lt;br /&gt;&lt;br /&gt;直覺就是到 SQL Server Configuration Manager 去修改 default TCP/IP port number&lt;br /&gt;&lt;br /&gt;可是後來想到.....其他設定不就沒辦法動了?&lt;br /&gt;&lt;br /&gt;因此後來改用 &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Alias &lt;/span&gt;來設定&lt;br /&gt;&lt;br /&gt;Google 了一下找到這一篇「&lt;a href="http://www.mssqltips.com/tip.asp?tip=1620"&gt;How to setup and use a SQL Server alias&lt;/a&gt;」&lt;br /&gt;&lt;br /&gt;很容易就完成設定囉!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-9222849913970338883?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/9222849913970338883/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=9222849913970338883' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9222849913970338883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/9222849913970338883'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/sql-server-alias.html' title='[SQL Server] Alias 的用法'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4845084462385232972</id><published>2009-06-02T13:47:00.002+08:00</published><updated>2009-06-02T13:51:31.022+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[Oracle] 如何做到 MySQL 中的 LIMIT 效果</title><content type='html'>用過 MySQL 的人應該知道&lt;br /&gt;&lt;br /&gt;若是要取得 Table A 的第 11~20 筆資料，只要透過 &lt;span style="font-weight: bold;"&gt;LIMIT&lt;/span&gt; 關鍵字就可以輕易取得!&lt;br /&gt;&lt;br /&gt;但若是在 Oracle 中想要達成這種效果呢?&lt;br /&gt;&lt;br /&gt;只要將 &lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;ROWNUM&lt;/span&gt; 以及 &lt;span style="font-weight: bold; color: rgb(51, 51, 255);"&gt;MINUS&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt; &lt;/span&gt;搭配使用就可以囉!&lt;br /&gt;&lt;br /&gt;以下有幾個參考連結：&lt;br /&gt;&lt;br /&gt;&lt;a href="http://study.zgsoung.idv.tw/2008/09/oraclerownum.html" target="_blank"&gt;新的開始: Oracle的Rownum的使用&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://shinlivespace.blogspot.com/2008/03/oracle-sql-select-rownum.html" target="_blank"&gt;丑角的天空: ORACLE : 列數限制查詢,SQL SELECT ROWNUM&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4845084462385232972?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4845084462385232972/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4845084462385232972' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4845084462385232972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4845084462385232972'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/06/oracle-mysql-limit.html' title='[Oracle] 如何做到 MySQL 中的 LIMIT 效果'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8242472494678787356</id><published>2009-05-20T16:12:00.002+08:00</published><updated>2009-05-20T16:13:11.471+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[.NET] 自訂屬性</title><content type='html'>之前在寫 .NET Web Service 的時候就覺得.......&lt;br /&gt;&lt;br /&gt;為什麼在 method 上面加個 &lt;b style="color: rgb(255, 0, 0);"&gt;[WebMethod]&lt;/b&gt; 就可以讓 method 變成 web service 提供給外部呼叫呢?&lt;br /&gt;&lt;br /&gt;若是要增加額外的描述，還可以使用 &lt;b style="color: rgb(0, 0, 255);"&gt;[WebMethod(Description = "xxxxxx")]&lt;/b&gt; 的方式來增加&lt;br /&gt;&lt;br /&gt;這到底是怎麼做到的呢?&lt;br /&gt;&lt;br /&gt;答案就是：&lt;b&gt;Custom Attributes (自訂屬性)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;搜尋了一下，在 MSDN 上面看到還算詳細的範例，網址如下：&lt;br /&gt;&lt;br /&gt;&lt;a title="MSDN &amp;gt;&amp;gt; MSDN Library &amp;gt;&amp;gt; 使用屬性擴充中繼資料" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/5x6cd29c%28VS.80%29.aspx" id="ijfx"&gt;MSDN &amp;gt;&amp;gt; MSDN Library &amp;gt;&amp;gt; 使用屬性擴充中繼資料&lt;/a&gt;  (&lt;a title="英文版" target="_blank" href="http://msdn.microsoft.com/en-us/library/5x6cd29c%28VS.80%29.aspx" id="kr1v"&gt;英文版&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;了解以後就可以撰寫自己的 attribute class 來用囉!&lt;br /&gt;&lt;br /&gt;PS. 其實 attribute class 就是一般的 class 而已，只不過因為繼承了 &lt;a title="System.Attribute" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.attribute%28VS.80%29.aspx" id="ao1o"&gt;System.Attribute&lt;/a&gt;  類別，因此有了 .NET Framework 所提供的自訂屬性的效果。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8242472494678787356?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8242472494678787356/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8242472494678787356' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8242472494678787356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8242472494678787356'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/05/net.html' title='[.NET] 自訂屬性'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7856229795450405754</id><published>2009-05-05T16:51:00.003+08:00</published><updated>2010-03-04T16:12:16.944+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><title type='text'>[.NET] C# 的新功能 - Automatic Properties &amp; Object Initializers &amp; Collection Initializers</title><content type='html'>今天在網路上看到&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/08/new-c-orcas-language-features-automatic-properties-object-initializers-and-collection-initializers.aspx" target="_blank"&gt;這篇文章&lt;/a&gt;.......&lt;br /&gt;&lt;br /&gt;才發現原來 C# 有提供這麼酷的功能&lt;br /&gt;&lt;br /&gt;Automatic Properties 可以讓 setter 與 getter 的宣告更為簡潔便利(前提是 property 沒有做額外的判斷與處理)&lt;br /&gt;&lt;br /&gt;Object Initializers 讓程式開發人員不需要一一指定物件的 property 來進行初始化&lt;br /&gt;&lt;br /&gt;Collection Initializers 更是可以一次初始化 collection 中的物件&lt;br /&gt;&lt;br /&gt;另外還有一篇文章也很值得參考：&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/06/06/c-3-auto-imp-prop.aspx" target="_blank"&gt;C# 3.0自動實作屬性的犀利之處 - 黑暗執行緒&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7856229795450405754?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7856229795450405754/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7856229795450405754' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7856229795450405754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7856229795450405754'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/05/net-c-automatic-properties-object.html' title='[.NET] C# 的新功能 - Automatic Properties &amp; Object Initializers &amp; Collection Initializers'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4645800503177210858</id><published>2009-04-30T14:36:00.003+08:00</published><updated>2009-04-30T16:09:40.997+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] 相依屬性(Dependency Property) 進階探討</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;b&gt;實作 Dependency Property(相依屬性) 的規則與流程&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;1、首先必須宣告 Dependency Property&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dependency Property 欄位都是 &lt;b style="color: rgb(255, 0, 0);"&gt;public&lt;/b&gt;、&lt;b style="color: rgb(0, 0, 255);"&gt;static&lt;/b&gt;，並且名稱以「&lt;b style="color: rgb(56, 118, 29);"&gt;Property&lt;/b&gt;」作為結尾。&lt;br /&gt;&lt;br /&gt;例如以下宣告：&lt;br /&gt;&lt;blockquote&gt;public static readonly DependencyProperty IsDefaultProperty;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;2、在 static 建構子中註冊 Dependency Property&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;由於 Dependency Property 必須呼叫 static 方法 &lt;a title="DependencyProperty.Register()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.register.aspx" id="gsxf"&gt;DependencyProperty.Register()&lt;/a&gt; 來建立&lt;br /&gt;&lt;br /&gt;而在註冊時，必須在 Register() method 中指定以下內容：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Dependency Property 的名稱&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Dependency Property 的型態&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;包含 Dependency Property 的 Class 型態&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Metadata (型態為 &lt;a title="FrameworkPropertyMetadata" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkpropertymetadata.aspx" id="vfva"&gt;FrameworkPropertyMetadata&lt;/a&gt;，而 Callback Function 宣告於此處)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;用來檢查 Property 的值是否合法的 function&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;3、設定 Getter 與 Setter&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dependency Property 宣告了就是用來設定或取值之用的，當然要設定 Getter 與 Setter 囉!&lt;br /&gt;&lt;br /&gt;但比較特別的是，Dependency Property 值的設定或取得，是透過 &lt;a title="System.Windows.DependencyObject" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.aspx" id="m7pp"&gt;System.Windows.DependencyObject&lt;/a&gt; 中的 &lt;a title="SetValue()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.setvalue.aspx" id="io2m"&gt;SetValue()&lt;/a&gt; 與 &lt;a title="GetValue()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyobject.getvalue.aspx" id="lstk"&gt;GetValue()&lt;/a&gt; 來處理的。&lt;br /&gt;&lt;br /&gt;而比較需要注意的是，若是有任何的程式邏輯或是檢查要加入，請記得加到 Callback Function 中，別加在 Getter 與 Setter 中，因為那只是用來取值或設定值之用。&lt;br /&gt;(所有 WPF 內建的屬性封裝都遵守此規則，因此別亂寫囉!)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;使用 Dependency Property 的優點 &amp;amp; 所提供的功能&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;1、節省記憶體&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;想像一下，Button 類別有將近 100 個欄位值，每個 Label 也將近有 90 個欄位值，若是畫面中有一堆 Button 與 Label 所產生的物件，記憶體的耗用量豈不是很可觀?&lt;br /&gt;&lt;br /&gt;沒錯，這就是 Dependency Property 所要解決的問題，透過 static 的方式先產生 Dependency Property，在將 Button 與 Label 物件的屬性「依附上去」。&lt;br /&gt;&lt;br /&gt;當每個 Button 或是 Label 都依附到同一個 Dependency Property，如此一來，記憶體的用量就會大大地減少囉!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;2、變更告知 (Change Notification)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;WPF 可以根據 Dependency Property 的 Metadata 自動觸法許多動作，例如：重新整理元素、更新畫面配置、重新整理資料繫結...等等。&lt;br /&gt;&lt;br /&gt;範例：以下程式實作滑鼠移到按鈕上後，更改文字顏色(Button 的 IsMouseOver 屬性被更改，自動觸發更改文字顏色)&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&lt;Window x:Class="WPF_Unleashed.CH03.AboutDialog"&lt;br /&gt;    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;    Title="About WPF Unleashed" SizeToContent="WidthAndHeight" Background="OrangeRed" FontSize="30" FontStyle="Italic"&gt;&lt;br /&gt;    &lt;StackPanel&gt;&lt;br /&gt;        &lt;Label FontWeight="Bold" FontSize="20" Foreground="White"&gt;WPF Unleashed (Version 3.0)&lt;/Label&gt;&lt;br /&gt;        &lt;Label&gt;2006 SAMS Publishing&lt;/Label&gt;&lt;br /&gt;        &lt;Label&gt;Installed Capters:&lt;/Label&gt;&lt;br /&gt;        &lt;ListBox&gt;&lt;br /&gt;            &lt;ListBoxItem&gt;Chapter 1&lt;/ListBoxItem&gt;&lt;br /&gt;            &lt;ListBoxItem&gt;Chapter 2&lt;/ListBoxItem&gt;&lt;br /&gt;        &lt;/ListBox&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Center"&gt;&lt;br /&gt;            &lt;br /&gt;            &lt;Button MinWidth="75" Margin="10" Content="Help"&gt;&lt;br /&gt;                &lt;!-- Button 的效果就設定在這邊 --&gt;&lt;br /&gt;                &lt;Button.Style&gt;&lt;br /&gt;                    &lt;Style  TargetType="{x:Type Button}"&gt;&lt;br /&gt;                        &lt;!--觸發事件的設定--&gt;&lt;br /&gt;                        &lt;Style.Triggers&gt;&lt;br /&gt;                            &lt;Trigger Property="IsMouseOver" Value="True"&gt;&lt;br /&gt;                                &lt;!--用這種方式就可以達到我們要的效果--&gt;&lt;br /&gt;                                &lt;Setter Property="Foreground" Value="Green"&gt;&lt;/Setter&gt;&lt;br /&gt;                            &lt;/Trigger&gt;&lt;br /&gt;                        &lt;/Style.Triggers&gt;&lt;br /&gt;                    &lt;/Style&gt;&lt;br /&gt;                &lt;/Button.Style&gt;&lt;br /&gt;            &lt;/Button&gt;&lt;br /&gt;            &lt;Button MinWidth="75" Margin="10"&gt;OK&lt;/Button&gt;&lt;br /&gt;        &lt;/StackPanel&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;StatusBar&gt;You have seccessfully registered this product.&lt;/StatusBar&gt;&lt;br /&gt;    &lt;/StackPanel&gt;&lt;br /&gt;&lt;/Window&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;3、屬性值繼承 (Property Value Inheritance)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;元素樹中，父節點的控制項屬性會向下套用到子系的控制項屬性。&lt;br /&gt;&lt;br /&gt;但也是有些例外的情況，原因可能會有兩種：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;在 DependencyProperty.Register() 裡，透過 FrameworkPropertyMetadata.Options.Inherits 設定為不繼承父系控制項的屬性值。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;子系控制項覆寫了繼承來的屬性值。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;4、支援多重提供者&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;WPF 中有許多屬性提供者可用不同的方式設定 Dependency Property，而屬性值的決定過程會經過五個步驟：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;b style="color: rgb(56, 118, 29);"&gt;判斷基底值&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;這個部分會由多種屬性提供者來提供值，優先順序為：&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Local Value&lt;/b&gt; -&amp;gt; &lt;b&gt;Style Trigger&lt;/b&gt; -&amp;gt; &lt;b&gt;Template Trigger&lt;/b&gt; -&amp;gt; &lt;b&gt;Style Setter&lt;/b&gt; -&amp;gt; &lt;b&gt;Theme Style Trigger&lt;/b&gt; -&amp;gt; &lt;b&gt;Theme Style Setters&lt;/b&gt; -&amp;gt; &lt;b&gt;Property Value Inheritance&lt;/b&gt; -&amp;gt; &lt;b&gt;Default Value&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(56, 118, 29);font-size:100%;" &gt;&lt;b&gt;驗算&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;此部份進行屬性值的驗算，為運算式。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(56, 118, 29);font-size:100%;" &gt;&lt;b&gt;套用動畫&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;若有一個以上的動畫正在執行，它們可以改變目前的屬性值，甚至完全置換掉。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(56, 118, 29);font-size:100%;" &gt;&lt;b&gt;轉換&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;若有註冊 CoerceValueCallback 委派，則屬性值會被傳遞到此 function 進行轉換，以取得更新後的值。&lt;br /&gt;(例如 ProgressBar 就是利用 callback function 來保持屬性值不會超過最大或最小值)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(56, 118, 29);font-size:100%;" &gt;&lt;b&gt;驗證&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;最後還會進行屬性值的驗證，決定該值是否合法。(若有設定 ValidateValueCallback 委派)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;&lt;br /&gt;5、附加屬性 (Attached Property)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;附加屬性(attached property)是種特殊的 Dependency Property，可以附加到任何物件上，以下直接用範例說明：&lt;br /&gt;&lt;pre class="brush: xml"&gt;&lt;br /&gt;&lt;Page x:Class="WPF_Unleashed.CH03.AboutDialog01"&lt;br /&gt;    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;br /&gt;    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&lt;br /&gt;    Title="About WPF Unleashed" Background="OrangeRed"&gt;&lt;br /&gt;    &lt;StackPanel&gt;&lt;br /&gt;        &lt;Label FontWeight="Bold" FontSize="20" Foreground="White"&gt;WPF Unleashed (Version 3.0)&lt;/Label&gt;&lt;br /&gt;        &lt;Label&gt;2006 SAMS Publishing&lt;/Label&gt;&lt;br /&gt;        &lt;Label&gt;Installed Chapters:&lt;/Label&gt;&lt;br /&gt;        &lt;ListBox&gt;&lt;br /&gt;            &lt;ListBoxItem&gt;Chapter 1&lt;/ListBoxItem&gt;&lt;br /&gt;            &lt;ListBoxItem&gt;Chapter 2&lt;/ListBoxItem&gt;&lt;br /&gt;        &lt;/ListBox&gt;&lt;br /&gt;        &lt;!--原本 StackPanel 是沒有 FontSize &amp; FontStyle 兩個屬性的--&gt;&lt;br /&gt;        &lt;!--但若是要同時設定 StackPanel 中控制項的 FontSize &amp; FontStyle 兩個屬性--&gt;&lt;br /&gt;        &lt;!--可以透過加入附加屬性的方式，也就是下方的 TextElement.FontSize &amp; TextElement.FontStyle 兩個屬性--&gt;&lt;br /&gt;        &lt;StackPanel Orientation="Horizontal" HorizontalAlignment="Center" TextElement.FontSize="30" TextElement.FontStyle="Italic"&gt;&lt;br /&gt;            &lt;Button MinWidth="75" Margin="10"&gt;Help&lt;/Button&gt;&lt;br /&gt;            &lt;Button MinWidth="75" Margin="10"&gt;OK&lt;/Button&gt;&lt;br /&gt;        &lt;/StackPanel&gt;&lt;br /&gt;        &lt;StatusBar&gt;You have seccessfully registered this product&lt;/StatusBar&gt;&lt;br /&gt;    &lt;/StackPanel&gt;&lt;br /&gt;&lt;/Page&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;從程式碼可以看出，透過附加屬性的使用，StackPanel 中的控制項就不用一一加上 FontSize &amp;amp; FontStyle 兩個屬性了。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="Anita 的.NET 世界: 什麼是Dependency Property" target="_blank" href="http://anita-lo.blogspot.com/2008/11/dependency-property.html" id="a10t"&gt;Anita 的.NET 世界: 什麼是Dependency Property&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="design studio: Dependency Property" href="http://nomadlibra.blogspot.com/2009/02/public-class-childclass.html" id="sw_7"&gt;design studio: Dependency Property&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="WPF Tutorial | Introduction to DependencyProperties" target="_blank" href="http://www.wpftutorial.net/HowToCreateADepProp.html" id="wn_0"&gt;WPF Tutorial | Introduction to DependencyProperties&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4645800503177210858?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4645800503177210858/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4645800503177210858' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4645800503177210858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4645800503177210858'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/wpf-dependency-property_30.html' title='[WPF] 相依屬性(Dependency Property) 進階探討'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-575884648730772266</id><published>2009-04-21T16:41:00.002+08:00</published><updated>2009-04-21T16:44:52.117+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>[.NET] SqlConnectionStringBuilder &amp; SQL Express</title><content type='html'>想必應該有人使用 SqlConnectionStringBuilder 來產生 SQL 字串吧!&lt;br /&gt;&lt;br /&gt;一般連到 SQL Server 時，在 DataSource 的部分都是指定 server 的 domain name 或是 IP address&lt;br /&gt;&lt;br /&gt;但若是連到 SQL Express 呢??&lt;br /&gt;&lt;br /&gt;以下以 localhost 為例，應該要輸入：&lt;br /&gt;&lt;blockquote&gt;DataSource = "(local)\SQLEXPRESS";&lt;br /&gt;&lt;/blockquote&gt;如此一來就會產生正確的資料庫連線字串了~&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-575884648730772266?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/575884648730772266/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=575884648730772266' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/575884648730772266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/575884648730772266'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/net-sqlconnectionstringbuilder-sql.html' title='[.NET] SqlConnectionStringBuilder &amp; SQL Express'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-5257673922630393878</id><published>2009-04-16T09:38:00.002+08:00</published><updated>2009-04-16T09:39:07.284+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>[Windows] 使用 .reg 檔案新增 &amp; 刪除登錄檔機碼</title><content type='html'>今天剛好遇到這個需求(&lt;b&gt;使用 .reg 檔案新增 &amp;amp; 刪除登錄檔機碼&lt;/b&gt;)，所以在網路上找到了蠻不錯的參考資料&lt;br&gt;&lt;br&gt;&lt;a title="如何使用登錄檔(.reg)進行新增、修改或刪除登錄機碼和值" target="_blank" href="http://blog.miniasp.com/post/2008/11/How-to-add-modify-delete-registry-subkeys-and-values-by-using-a-registration-entries-reg-file.aspx" id="llo1"&gt;如何使用登錄檔(.reg)進行新增、修改或刪除登錄機碼和值&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a title="利用登錄檔來刪除機碼 - 教學文章 - 卡拉娛樂網 論壇|娛樂|影音|分享|下載" target="_blank" href="http://www.karayou.com/viewthread.php?tid=152233&amp;amp;extra=page%3D16" id="zv64"&gt;利用登錄檔來刪除機碼 - 教學文章 - 卡拉娛樂網 論壇|娛樂|影音|分享|下載&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;新增比較容易，而刪除的話可以開啟登錄檔編輯程式(&lt;b&gt;開始 -&amp;gt; 執行 -&amp;gt; regedit&lt;/b&gt;)，將要刪除的機碼匯出，並進行編輯，在每個機碼前面加上「&lt;b style="color: rgb(255, 0, 0);"&gt;-&lt;/b&gt;」即可。&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-5257673922630393878?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/5257673922630393878/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=5257673922630393878' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/5257673922630393878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/5257673922630393878'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/windows-reg.html' title='[Windows] 使用 .reg 檔案新增 &amp;amp; 刪除登錄檔機碼'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7530504563391112033</id><published>2009-04-07T14:57:00.003+08:00</published><updated>2011-05-27T11:47:54.847+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[Oracle] 如何使用流水號</title><content type='html'>比起 MS SQL Server 或是 MySQL，Oracle 使用流水號可以說是相當麻煩阿.......&lt;br&gt;&lt;br&gt;怎麼說呢?&lt;br&gt;&lt;br&gt;因為 int 欄位無法直接透過遞增的方式產生流水號，而是必須使用 sequence 搭配 trigger 來進行&lt;br&gt;&lt;br&gt;因此整個過程必須分為三個步驟：&lt;br&gt;&lt;ol&gt;&lt;li&gt;建立 table&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;建立 sequence，用來取得新的遞增值&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;建立 trigger，在新的資料存入 table 時，將新的遞增值存入 table 中&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;以下直接用範例來說明：&lt;br&gt;&lt;br /&gt;&lt;pre name="code" class="sql"&gt;&lt;br /&gt;-- 建立 sequence 作流水號之用&lt;br /&gt;CREATE SEQUENCE seq_user_group&lt;br /&gt;    INCREMENT BY 1&lt;br /&gt;    START WITH 1&lt;br /&gt;    ORDER;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- 組別&lt;br /&gt;CREATE TABLE user_group (&lt;br /&gt;    group_id            NUMBER  NOT NULL,   -- 群組 ID&lt;br /&gt;    group_name          NVARCHAR2(100),     -- 組別名稱&lt;br /&gt;    remark              NVARCHAR2(200)      -- 備註&lt;br /&gt;    parent_group_id     NUMBER,             --父組別 ID&lt;br /&gt;    &lt;br /&gt;    CONSTRAINT pk_user_group PRIMARY KEY(group_id)&lt;br /&gt;);&lt;br /&gt;COMMENT ON TABLE user_group is '組別';&lt;br /&gt;COMMENT ON COLUMN user_group.group_id is '群組 ID';&lt;br /&gt;COMMENT ON COLUMN user_group.group_name is '組別名稱';&lt;br /&gt;COMMENT ON COLUMN user_group.remark is '備註';&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- 建立 trigger 以產生遞增欄位 (for user_group)&lt;br /&gt;CREATE TRIGGER tri_auto_increment_user_group&lt;br /&gt;    BEFORE INSERT ON user_group &lt;br /&gt;    FOR EACH ROW&lt;br /&gt;    BEGIN&lt;br /&gt;        SELECT seq_user_group.NEXTVAL INTO :NEW.group_id FROM DUAL;&lt;br /&gt;    END;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7530504563391112033?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7530504563391112033/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7530504563391112033' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7530504563391112033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7530504563391112033'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/oracle.html' title='[Oracle] 如何使用流水號'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2930783585919779944</id><published>2009-04-07T09:50:00.004+08:00</published><updated>2009-04-30T16:10:53.581+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] Routed 輸入事件</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;b&gt;Routed Event&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;假設 element tree 如下：&lt;br /&gt;&lt;br /&gt;                Window&lt;br /&gt;                    |&lt;br /&gt;                  Grid&lt;br /&gt;                    |&lt;br /&gt;   ---------------------------&lt;br /&gt;   |                |                  |&lt;br /&gt;Button       TextBlock    ScrollViewer&lt;br /&gt;   |                                    |&lt;br /&gt;TextBlock                    StackPanel&lt;br /&gt;                                        |&lt;br /&gt;                                   TextBlock&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;而 Routed Event Handler 大概長以下這樣：&lt;br /&gt;&lt;blockquote&gt;void functionName(object sender, RoutedEventArgs args)&lt;br /&gt;{ ....(事件處理)... }&lt;br /&gt;&lt;/blockquote&gt;其中參數的部份有幾個重點：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sender：此物件將 event 送到 application 中&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;args.Source：真正導致 event 發生的 element&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;若是在 element tree 中左下角的 TextBlock 按一下滑鼠右鍵，分別會產生出以下的 event：&lt;br /&gt;&lt;blockquote&gt;PreviewMouseDown -&amp;gt; MouseDown&lt;br /&gt;&lt;/blockquote&gt;其中 sender 的部份，觸發 event 順序如下：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;PreviewMouseDown：Window -&amp;gt; Grid -&amp;gt; Button -&amp;gt; TextBlock&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;MouseDown：TextBlock -&amp;gt; Button -&amp;gt; Grid -&amp;gt; Window&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;因此從上面可以知道，&lt;b style="color: rgb(255, 0, 0);"&gt;PreviewMouseDown 是屬於 tunneling event&lt;/b&gt;、&lt;b style="color: rgb(0, 0, 255);"&gt;MouseDown 屬於 bubbling event&lt;/b&gt;。&lt;br /&gt;&lt;br /&gt;而透過 Event Routing 的特性，若是要讓較上層的 element 先處理 mouse down 的動作，可以撰寫在 PreviewMouseDown 中。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Mouse Event&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;MouseDown 與 MouseUp 不一定會同時出現&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;例如：在視窗中按下按鈕，會發生 MouseDown event，但如果持續按著不放，再離開視窗的範圍後再放開滑鼠，不會出現 MouseUp event。&lt;br /&gt;&lt;br /&gt;因此，若要解決此問題，可以透過在 &lt;a title="UIElement" href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.aspx" id="fbo-"&gt;UIElement&lt;/a&gt; 或 &lt;a title="ContentElement" href="http://msdn.microsoft.com/en-us/library/system.windows.contentelement.aspx" id="bo7n"&gt;ContentElement&lt;/a&gt; 中所定義的 CaptureMouse 方法來解決。&lt;br /&gt;&lt;br /&gt;當呼叫了 CaptureMouse 方法後，即使滑鼠離開視窗，視窗也會持續的接收 MouseMove 與 MouseUp 事件。&lt;br /&gt;&lt;br /&gt;最後當 MouseUp 事件處理完成後，可以呼叫 ReleaseMouseCapture 或是設定 Mouse.Capture 為 null 來釋放所捕捉的滑鼠。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Keyboard Event&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在 WPF 中，keyboard event 都會下放到 TextBox、RichTextBox、ScrollViewer 這一類的控制項中作處理。&lt;br /&gt;&lt;br /&gt;需要注意的是，只有當 element 或是控制項具有鍵盤焦點時，才會是 keyboard event 的來源。&lt;br /&gt;&lt;br /&gt;此外，keyboard event 亦屬於 routed event，因此具有焦點的 element 的所有上層 element，都可以參與 keyboard event，且其 &lt;a title="IsKeyboardFocusWithin" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.iskeyboardfocuswithin.aspx" id="ut9x"&gt;IsKeyboardFocusWithin&lt;/a&gt; 屬性都會是 true。&lt;br /&gt;&lt;br /&gt;當 element 獲得 or 失去焦點時，會觸發 &lt;a title="GotKeyboardFocus" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.windows.uielement.gotkeyboardfocus.aspx" id="swnn"&gt;GotKeyboardFocus&lt;/a&gt; 與 &lt;a title="LostKeyboardfocus" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.windows.uielement.lostkeyboardfocus.aspx" id="p_iq"&gt;LostKeyboardfocus&lt;/a&gt; 事件，也都是 routed event；此外，由於兩個事件屬於 tunneling event，因此在 element tree 中上方的 element 可以先察覺到焦點的改變。&lt;br /&gt;&lt;br /&gt;而 Keyboard 的輸入包含了三種 event，發生順序如下：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;KeyDown (參數型態為 &lt;a title="KeyEventArgs" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.aspx" id="egzb"&gt;KeyEventArgs&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;TextInput (參數型態為 &lt;a title="TextCompositionEventArgs" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.input.textcompositioneventargs.aspx" id="jup9"&gt;TextCompositionEventArgs&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;KeyUp (參數型態為 &lt;a title="KeyEventArgs" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.aspx" id="uyxa"&gt;KeyEventArgs&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;但比較需要注意的是，若按下的是「Shift」、方向鍵、或是其他功能鍵，並不會產生 TextInput 事件。舉例來說，或先按下 Shift 再按 A，一共會觸發兩次 KeyDown 事件、一次 TextInput 事件、兩次 KeyUp 事件。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2930783585919779944?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2930783585919779944/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2930783585919779944' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2930783585919779944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2930783585919779944'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/wpf-routed.html' title='[WPF] Routed 輸入事件'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3551901176304656320</id><published>2009-04-01T13:18:00.008+08:00</published><updated>2009-04-30T16:16:00.772+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] 相依屬性(Dependency Property) 初探</title><content type='html'>在傳統的 Window Form 中的設計中，每個控制項都各自擁有自己的 property，而這些 property 大多都是相同的(例如：FontSize)，因此不僅浪費記憶體來儲存這些 property 的值，有時在程式中還需要撰寫多餘程式來設定這些 property 的值。&lt;br /&gt;&lt;br /&gt;因此，在 WPF 中提出了Dependency Property，用來解決各控制項中重複的 property 過多因此造成浪費記憶體的現象。&lt;br /&gt;&lt;br /&gt;以下用範例程式來說明：(節錄自 &lt;a title="Application = Code + Markup" target="_blank" href="http://www.charlespetzold.com/wpf/" id="hz2t"&gt;Application = Code + Markup&lt;/a&gt;  一書)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SpaceButton.cs&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;&lt;br /&gt;namespace CH08.SetSpaceProperty&lt;br /&gt;{&lt;br /&gt;   public class SpaceButton : Button&lt;br /&gt;   {&lt;br /&gt;       //傳統 .NET 做法：私有欄位搭配公開 property&lt;br /&gt;       string _txt;&lt;br /&gt;&lt;br /&gt;       //透過 get &amp;amp; set 設定 property 的處理方式&lt;br /&gt;       public string Text&lt;br /&gt;       {&lt;br /&gt;           set&lt;br /&gt;           {&lt;br /&gt;               _txt = value;&lt;br /&gt;               this.Content = SpaceOutText(_txt);&lt;br /&gt;           }&lt;br /&gt;           get { return _txt; }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //Dependecy Property 的宣告&lt;br /&gt;       public static readonly DependencyProperty SpaceProperty;&lt;br /&gt;       public int Space&lt;br /&gt;       {&lt;br /&gt;           //不同與以往 property 的設定方式&lt;br /&gt;           //Dependency Property 必須透過 DependencyObject 中的 SetValue() 與 GetValue() 進行 value 的處理&lt;br /&gt;           //*** SetValue() 與 GetValue() 皆為 static method ***&lt;br /&gt;           set { SetValue(SpaceProperty, value); }&lt;br /&gt;           get { return (int)GetValue(SpaceProperty); }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //處理 Dependency Property 必須使用 static constructor&lt;br /&gt;       static SpaceButton()&lt;br /&gt;       {&lt;br /&gt;           //設定 metadata (可以想像成是 Dependency Property 的相關特性)&lt;br /&gt;           FrameworkPropertyMetadata meta = new FrameworkPropertyMetadata();&lt;br /&gt;           meta.DefaultValue = 1;&lt;br /&gt;           meta.AffectsMeasure = true;&lt;br /&gt;           meta.Inherits = true;&lt;br /&gt;           meta.PropertyChangedCallback += OnSpacePropertyChanged;&lt;br /&gt;&lt;br /&gt;           //註冊 DependecyProperty&lt;br /&gt;           SpaceProperty = DependencyProperty.Register("Space", typeof(int), typeof(SpaceButton), meta, ValidateSpaceValue);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //value 檢驗時呼叫方法&lt;br /&gt;       static bool ValidateSpaceValue(object obj)&lt;br /&gt;       {&lt;br /&gt;           int i = (int)obj;&lt;br /&gt;           return i &gt;= 0;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       //當 property 改變時，呼叫此方法&lt;br /&gt;       static void OnSpacePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)&lt;br /&gt;       {&lt;br /&gt;           SpaceButton btn = obj as SpaceButton;&lt;br /&gt;           btn.Content = btn.SpaceOutText(btn._txt);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //在 Button Content 中每個字元間塞指定數量(Space)的空白&lt;br /&gt;       string SpaceOutText(string str)&lt;br /&gt;       {&lt;br /&gt;           if (str == null)&lt;br /&gt;               return null;&lt;br /&gt;&lt;br /&gt;           StringBuilder build = new StringBuilder();&lt;br /&gt;           foreach (char ch in str)&lt;br /&gt;               build.Append(ch + new string(' ', Space));&lt;br /&gt;&lt;br /&gt;           return build.ToString();&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SpaceWindow.cs&lt;/b&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;&lt;br /&gt;namespace CH08.SetSpaceProperty&lt;br /&gt;{&lt;br /&gt;   public class SpaceWindow : Window&lt;br /&gt;   {&lt;br /&gt;       //設定 Dependency Property&lt;br /&gt;       public static readonly DependencyProperty SpaceProperty;&lt;br /&gt;&lt;br /&gt;       public int Space&lt;br /&gt;       {&lt;br /&gt;           //同樣的，這邊也要透過 DependencyObject 中的 SetValue() 與 GetValue() 進行 value 的處理&lt;br /&gt;           set { SetValue(SpaceProperty, value); }&lt;br /&gt;           get { return (int)GetValue(SpaceProperty); }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       //處理 Dependency Property 必須使用 static constructor&lt;br /&gt;       static SpaceWindow()&lt;br /&gt;       {&lt;br /&gt;           //設定 metadata&lt;br /&gt;           FrameworkPropertyMetadata meta = new FrameworkPropertyMetadata();&lt;br /&gt;           meta.Inherits = true;&lt;br /&gt;&lt;br /&gt;           //由於 SpaceProperty 在 SpaceButton 中已經宣告過&lt;br /&gt;           //因此這邊直接將 SpaceProperty 指到 SpaceButton 中的 SpaceProperty&lt;br /&gt;           //只要透過 AddOwner() 將自己也設定為該 Dependency Property 的擁有者即可&lt;br /&gt;           SpaceProperty = SpaceButton.SpaceProperty.AddOwner(typeof(SpaceWindow));&lt;br /&gt;&lt;br /&gt;           //唯一需要注意的是 metadata 並不會一同被採用&lt;br /&gt;           //因此需要另外的宣告與設定，並 override&lt;br /&gt;           SpaceProperty.OverrideMetadata(typeof(SpaceWindow), meta);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SetSpaceProperty.cs&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;&lt;br /&gt;namespace CH08.SetSpaceProperty&lt;br /&gt;{&lt;br /&gt;    public class SetSpaceProperty : SpaceWindow&lt;br /&gt;    {&lt;br /&gt;        [STAThread]&lt;br /&gt;        public static void Main()&lt;br /&gt;        {&lt;br /&gt;            Application app = new Application();&lt;br /&gt;            app.Run(new SetSpaceProperty());&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public SetSpaceProperty()&lt;br /&gt;        {&lt;br /&gt;            this.Title = "Set Space Property";&lt;br /&gt;            this.SizeToContent = SizeToContent.WidthAndHeight;&lt;br /&gt;            this.ResizeMode = ResizeMode.CanMinimize;&lt;br /&gt;&lt;br /&gt;            int[] iSpaces = { 0, 1, 2 };&lt;br /&gt;            Grid grid = new Grid();&lt;br /&gt;            this.Content = grid;&lt;br /&gt;&lt;br /&gt;            //設定 Grid 的 RowDefinition&lt;br /&gt;            for (int i = 0; i &lt; 2; i++)&lt;br /&gt;            {&lt;br /&gt;                RowDefinition row = new RowDefinition();&lt;br /&gt;                row.Height = GridLength.Auto;&lt;br /&gt;                grid.RowDefinitions.Add(row);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            //設定 Grid 的 ColumnDefinition&lt;br /&gt;            for (int i = 0; i &lt; iSpaces.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                ColumnDefinition col = new ColumnDefinition();&lt;br /&gt;                col.Width = GridLength.Auto;&lt;br /&gt;                grid.ColumnDefinitions.Add(col);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; iSpaces.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                SpaceButton btn = new SpaceButton();&lt;br /&gt;                btn.Text = "Set window Space to " + iSpaces[i];&lt;br /&gt;                btn.Tag = iSpaces[i];&lt;br /&gt;                btn.HorizontalAlignment = HorizontalAlignment.Center;&lt;br /&gt;                btn.VerticalAlignment = VerticalAlignment.Center;&lt;br /&gt;                btn.Click += WindowPropertyOnClick;&lt;br /&gt;                grid.Children.Add(btn);&lt;br /&gt;                Grid.SetRow(btn, 0);&lt;br /&gt;                Grid.SetColumn(btn, i);&lt;br /&gt;&lt;br /&gt;                btn = new SpaceButton();&lt;br /&gt;                btn.Text = "Set button Space to " + iSpaces[i];&lt;br /&gt;                btn.Tag = iSpaces[i];&lt;br /&gt;                btn.HorizontalAlignment = HorizontalAlignment.Center;&lt;br /&gt;                btn.VerticalAlignment = VerticalAlignment.Center;&lt;br /&gt;                btn.Click += ButtonPropertyOnClick;&lt;br /&gt;                grid.Children.Add(btn);&lt;br /&gt;                Grid.SetRow(btn, 1);&lt;br /&gt;                Grid.SetColumn(btn, i);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //更改 Window 中的 Dependency Property&lt;br /&gt;        void WindowPropertyOnClick(object sender, RoutedEventArgs args)&lt;br /&gt;        {&lt;br /&gt;            SpaceButton btn = args.Source as SpaceButton;&lt;br /&gt;&lt;br /&gt;            //修改 Window 的 Space Dependency Property&lt;br /&gt;            //而此修改會影響所有在 SpaceWindow 中且擁有 SpaceProperty 屬性的控制項&lt;br /&gt;            //唯獨已經設定 Space 值的 SpaceButton 控制項例外&lt;br /&gt;            Space = (int)btn.Tag;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        //更改 Button 中的 Dependency Property&lt;br /&gt;        void ButtonPropertyOnClick(object sender, RoutedEventArgs args)&lt;br /&gt;        {&lt;br /&gt;            SpaceButton btn = args.Source as SpaceButton;&lt;br /&gt;&lt;br /&gt;            //僅單獨修改 SpaceButton 中的 Space 值&lt;br /&gt;            //不會影響到 SpaceWindow 中其他擁有 SpaceProperty 的控制項&lt;br /&gt;            btn.Space = (int)btn.Tag;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Anita 的.NET 世界: 什麼是Dependency Property" target="_blank" href="http://anita-lo.blogspot.com/2008/11/dependency-property.html" id="a10t"&gt;Anita 的.NET 世界: 什麼是Dependency Property&lt;/a&gt;&lt;a title="design studio: Dependency Property" href="http://nomadlibra.blogspot.com/2009/02/public-class-childclass.html" id="sw_7"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="design studio: Dependency Property" href="http://nomadlibra.blogspot.com/2009/02/public-class-childclass.html" id="sw_7"&gt;design studio: Dependency Property&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3551901176304656320?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3551901176304656320/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3551901176304656320' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3551901176304656320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3551901176304656320'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/wpf-dependency-property.html' title='[WPF] 相依屬性(Dependency Property) 初探'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8607061178173554742</id><published>2009-04-01T10:01:00.003+08:00</published><updated>2009-04-30T16:16:41.357+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] Layout</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;b&gt;Panel&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;從 &lt;a title="ContentControl" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.aspx" id="uf0-"&gt;ContentControl&lt;/a&gt; 中衍生出來的 class 都有 Content 屬性，幾乎可以被設定為任何物件，但問題在於「&lt;b style="color: rgb(255, 0, 0);"&gt;Content 只能設定一個物件&lt;/b&gt;」。&lt;br /&gt;&lt;br /&gt;然而一個視窗中怎麼可能只放一個物件呢? 因此在 WPF 中使用了 Panel 作為解決此問題的方式，而 Panel 的階層與衍生類別如下：&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;a title="UIElement" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.uielement.aspx" id="jswz"&gt;UIElement&lt;/a&gt; &lt;div style="margin-left: 40px;"&gt;&lt;a title="FrameworkElement" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.aspx" id="o.n_"&gt;FrameworkElement&lt;/a&gt; &lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;a title="Panel" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.aspx" id="rs30"&gt;Panel&lt;/a&gt; &lt;/div&gt;&lt;/div&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;div style="margin-left: 40px;"&gt;&lt;a title="Canvas" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.aspx" id="l2nl"&gt;Canvas&lt;/a&gt;&lt;br /&gt;&lt;a title="DockPanel" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.aspx" id="p073"&gt;DockPanel&lt;/a&gt;&lt;br /&gt;&lt;a title="Grid" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.aspx" id="k08n"&gt;Grid&lt;/a&gt;&lt;br /&gt;&lt;a title="StackPanel" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.stackpanel.aspx" id="g2ym"&gt;StackPanel&lt;/a&gt;&lt;br /&gt;&lt;a title="UniformGrid" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.uniformgrid.aspx" id="m_h-"&gt;UniformGrid&lt;/a&gt;&lt;br /&gt;&lt;a title="WrapPanel" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.wrappanel.aspx" id="plvf"&gt;WrapPanel&lt;/a&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;每種不同的 panel 有其自訂的 layout model，例如：&lt;br /&gt;&lt;br /&gt;StackPanel 用水平或垂直 stack 的方式安排子元素&lt;br /&gt;&lt;br /&gt;WrapPanel 類似 StackPanel，但可以將自動將元素擺到下一個 columm 或是 row 的位置&lt;br /&gt;&lt;br /&gt;DockPanel 則會根據 parent container 的內部邊界來進行自動擺設&lt;br /&gt;&lt;br /&gt;Grid 則是把所有子元素以格子狀的方式擺設&lt;br /&gt;&lt;br /&gt;UniformGrid 則是所有的行都等寬，列都等高&lt;br /&gt;&lt;br /&gt;Canvas 則是最貼近原本的做法，每個元素都有自己的座標位置&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Dock&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;重點就在於 dock 的位置了，分別是 Top、Bottom、Left、Right 四種，如果將控制項的 HorizontalAlignment 設定為 Center，整個版面會變得很奇怪，因此在撰寫上要注意一下。&lt;br /&gt;&lt;br /&gt;element 的定位必須使用 &lt;a title="DockPanel.SetDock()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.dockpanel.setdock.aspx" id="lxpa"&gt;DockPanel.SetDock()&lt;/a&gt; 來處理。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Grid&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;蠻龜毛的一個 layout panel，必須要先定義 &lt;a title="RowDefinition" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.rowdefinition.aspx" id="h:.2"&gt;RowDefinition&lt;/a&gt; 以及 &lt;a title="ColumnDefinition" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.columndefinition.aspx" id="ps4t"&gt;ColumnDefinition&lt;/a&gt; 並加入到 Grid 中，才能將控制項加入到 Grid 中。&lt;br /&gt;&lt;br /&gt;而控制項加入時還要透過 &lt;a title="Grid.SetRow()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setrow.aspx" id="c5.v"&gt;Grid.SetRow()&lt;/a&gt; 以及 &lt;a title="Grid.SetColumn()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setcolumn.aspx" id="rvum"&gt;Grid.SetColumn()&lt;/a&gt; 來設定控制項在 Grid 中的位置。&lt;br /&gt;&lt;br /&gt;element 的定位必須使用 &lt;a title="Grid.SetRow()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setrow.aspx" id="a2we"&gt;Grid.SetRow()&lt;/a&gt;、&lt;a title="Grid.SetColumn()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setcolumn.aspx" id="a2o9"&gt;Grid.SetColumn()&lt;/a&gt;、&lt;a title="Grid.SetRowSpan()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setrowspan.aspx" id="v48t"&gt;Grid.SetRowSpan()&lt;/a&gt;、&lt;a title="Grid.SetColumnSpan()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.setcolumnspan.aspx" id="f7x1"&gt;Grid.SetColumnSpan()&lt;/a&gt; 來處理。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;b&gt;Canvas&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;element 的定位必須使用 &lt;a title="Canvas.SetLeft()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.setleft.aspx" id="y4bi"&gt;Canvas.SetLeft()&lt;/a&gt;、&lt;a title="Canvas.SetTop()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.settop.aspx" id="dkf9"&gt;Canvas.SetTop()&lt;/a&gt;、&lt;a title="Canvas.SetRight()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.setright.aspx" id="tmc0"&gt;Canvas.SetRight()&lt;/a&gt;、&lt;a title="Canvas.SetBottom()" target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.canvas.setbottom.aspx" id="oaod"&gt;Canvas.SetBottom()&lt;/a&gt; 等方法來處理。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;事件處理&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;若將 event 處理指定給特定的控制項，例如：&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;Button.Click += ButtonOnClick;&lt;br /&gt;&lt;br /&gt;void ButtonOnClick(object sender, RoutedEventArgs args)&lt;br /&gt;{&lt;br /&gt;    MessageBox.Show("Hello");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;當然，也可以把 event 透過 this.AddHandler 註冊給 Window 物件(包含 Button)，但是就要在 function 中透過 args.Source 來判斷控制項的型態了，設定方式如下：&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;&lt;br /&gt;this.AddHandler(Button.ClickEvent, new RoutedEventHandler(ButtonOnClick));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;既然可以將 event 註冊給 Window 物件，當然也可以註冊給 Panel 物件囉!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8607061178173554742?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8607061178173554742/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8607061178173554742' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8607061178173554742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8607061178173554742'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/04/wpf-layout.html' title='[WPF] Layout'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3301408025446428401</id><published>2009-03-17T08:24:00.003+08:00</published><updated>2009-04-30T16:16:49.395+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WPF'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>[WPF] 學習資源</title><content type='html'>(陸陸續續持續更新.........)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;MSDN&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="Windows Presentation Foundation" target="_blank" href="http://msdn.microsoft.com/en-us/library/ms754130.aspx" id="h9lu"&gt;Windows Presentation Foundation&lt;/a&gt;  (&lt;a title="中文版" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/ms754130.aspx" id="xonm"&gt;中文版&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Tutorial&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="WPF Tutorial" target="_blank" href="http://www.wpftutorial.net/" id="f3dx"&gt;WPF Tutorial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dependency Properties&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="Anita 的.NET 世界: 什麼是Dependency Property" target="_blank" href="http://anita-lo.blogspot.com/2008/11/dependency-property.html" id="a10t"&gt;Anita 的.NET 世界: 什麼是Dependency Property&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="WPF Tutorial | Introduction to DependencyProperties" target="_blank" href="http://www.wpftutorial.net/HowToCreateADepProp.html" id="wn_0"&gt;WPF Tutorial | Introduction to DependencyProperties&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;WPF &amp;amp; Silverlight&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="Moli@Microsoft : WPF和Silverlight到底有什麼不同?" target="_blank" href="http://blogs.msdn.com/senwang/archive/2007/04/17/wpf-silverlight.aspx" id="jc36"&gt;Moli@Microsoft : WPF和Silverlight到底有什麼不同?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3301408025446428401?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3301408025446428401/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3301408025446428401' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3301408025446428401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3301408025446428401'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/03/wpf.html' title='[WPF] 學習資源'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2777676064189459617</id><published>2009-03-12T13:18:00.002+08:00</published><updated>2011-05-27T11:47:54.848+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='CSharp'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[C#] 在 Oracle 上一次執行多個 SQL 命令</title><content type='html'>一般在 ADO.NET 的批次處理部份，都是在 DataSet 進行離線的處理完後，透過 SqlDataAdapter(或是 OracleDataAdapter) 搭配 SqlCommandBuilder(或是 OracleCommandBuilder) 來做!&lt;br /&gt;&lt;br /&gt;若是對同一個 table 進行大量的 insert，也可以改用 bind parameter array 的方式進行批次新增&lt;br /&gt;&lt;br /&gt;但如果要處理的多個指令都不太一樣呢? 有 update、insert、delete 這時要怎麼辦?&lt;br /&gt;&lt;br /&gt;每個 SQL 都要重新產生 connection 物件或是 command 物件真是成本太大了。因此，若是使用的資料庫為 &lt;b style="color: rgb(255, 0, 0);"&gt;Oracle &lt;/b&gt;(MS SQL Server 不確定能不能這樣做)，可以將所有的 SQL 語法組合成以下的樣子：&lt;br /&gt;&lt;blockquote&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;BEGIN&lt;br /&gt;&lt;br /&gt;第一個 SQL 命令;&lt;br /&gt;&lt;br /&gt;第二個 SQL 命令;&lt;br /&gt;&lt;br /&gt;第三個 SQL 命令;&lt;br /&gt;&lt;br /&gt;.......&lt;br /&gt;&lt;br /&gt;.......&lt;br /&gt;&lt;br /&gt;END;&lt;/b&gt;&lt;br /&gt;&lt;/blockquote&gt;最後在 END 之後也是要補一個分號。&lt;br /&gt;&lt;br /&gt;當所有 SQL 語法組合而成上面的格式後，就可以透過一個 command 與一個 connection 一次將 SQL 命令丟給資料庫去作囉!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="MSDN Library &amp;gt;&amp;gt; Performing Batch Operations Using DataAdapters (ADO.NET)" target="_blank" href="http://msdn.microsoft.com/en-us/library/aadf8fk2.aspx" id="f9j_"&gt;MSDN Library &amp;gt;&amp;gt; Performing Batch Operations Using DataAdapters (ADO.NET)&lt;/a&gt; (&lt;a title="中文版" target="_blank" href="http://msdn.microsoft.com/zh-tw/library/aadf8fk2.aspx" id="fqma"&gt;中文版&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;a title="ADO.Net實現Oracle大批量數據的更新優化 - 中國自學編程網" target="_blank" href="http://www.zxbc.cn/html/20080120/31475.html" id="cq83"&gt;ADO.Net實現Oracle大批量數據的更新優化 - 中國自學編程網&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a title="oracle 一次執行多個sql的問題 - 白虎的地盤 - CSDNBlog" target="_blank" href="http://blog.csdn.net/bhsky/archive/2008/10/29/3173583.aspx" id="o0w6"&gt;oracle 一次執行多個sql的問題 - 白虎的地盤 - CSDNBlog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2777676064189459617?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2777676064189459617/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2777676064189459617' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2777676064189459617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2777676064189459617'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/03/c-oracle-sql.html' title='[C#] 在 Oracle 上一次執行多個 SQL 命令'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1832745278730748276</id><published>2009-02-25T17:35:00.001+08:00</published><updated>2011-05-27T11:47:54.849+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WebDevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>資料庫連線字串大全</title><content type='html'>在網路上偶然看到以下這個網站：&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.connectionstrings.com/"&gt;ConnectionStrings.com - Forgot that connection string? Get it here!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;大概想的到的資料庫都在裡面了......(當然，想不到的也有一大堆)&lt;br /&gt;&lt;br /&gt;以後忘記連線字串怎麼寫就可以連進去參考囉!&lt;br /&gt;&lt;br /&gt;當然，也可以透過 ConnectionStringBuilder 類別來產生......&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1832745278730748276?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1832745278730748276/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1832745278730748276' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1832745278730748276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1832745278730748276'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/blog-post.html' title='資料庫連線字串大全'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1442923572568283297</id><published>2009-02-20T14:00:00.002+08:00</published><updated>2009-02-20T14:02:15.567+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>[JavaScript] expando 屬性的定義與使用</title><content type='html'>最近在讀 Learning Jquery 時，看見 JavaScript expando，是個蠻有意思的東西，可以自行擴充 JavaScript object 的屬性。&lt;br /&gt;&lt;br /&gt;而由於這些屬性是放置於 memory 中，因此使用起來速度較快，不過也要記得釋放，免得出現 memory leak 的問題。&lt;br /&gt;&lt;br /&gt;在網路上查詢到以下的範例(內容有稍作修改)，說明 JavaScript expando 的使用方式：&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;   &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/span&gt; myObj = &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt; Object&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;toString&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;    &lt;span style="color: rgb(0, 153, 0);"&gt;//出現 "[object Object]"&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;//設定 expando 屬性&lt;/span&gt;&lt;br /&gt;   myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;myExpando&lt;/span&gt; = &lt;span style="color: rgb(51, 102, 204);"&gt;"Hello Expando"&lt;/span&gt;;&lt;br /&gt;   myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;toString&lt;/span&gt; = &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;    &lt;span style="color: rgb(0, 153, 0);"&gt;//override toString() method&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;myExpando&lt;/span&gt;;&lt;br /&gt;   &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;toString&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;    &lt;span style="color: rgb(0, 153, 0);"&gt;//出現 "Hello Expando"&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;//設定 expando 屬性&lt;/span&gt;&lt;br /&gt;   myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;reportTime&lt;/span&gt; = &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;new&lt;/b&gt;&lt;/span&gt; Date&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;   &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;br /&gt;   myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;reportTime&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;; &lt;span style="color: rgb(0, 153, 0);"&gt;//出現目前的日期與時間&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;//刪除 expando 屬性&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;delete&lt;/b&gt;&lt;/span&gt; myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;reportTime&lt;/span&gt;;&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;//再一次嘗試呼叫已經刪除的 expando 屬性&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;try&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;       myObj.&lt;span style="color: rgb(0, 102, 0);"&gt;reportTime&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;   &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt; &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;catch&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;e&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;e.&lt;span style="color: rgb(0, 102, 0);"&gt;message&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;   &lt;span style="color: rgb(0, 153, 0);"&gt;//出現 "myObj.reportTime is not a function"&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Kakashi's Blog::javascript with expando properties - blog.ncu.edu.tw" target="_blank" href="http://kakashi.blog.ncu.edu.tw/?8774" id="ff4a"&gt;Kakashi's Blog::javascript with expando properties - blog.ncu.edu.tw&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Develocity: Presto Expando" target="_blank" href="http://develocity.blogspot.com/2007/04/its-hard-to-know-where-to-start-but.html" id="c0wj"&gt;Develocity: Presto Expando&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1442923572568283297?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1442923572568283297/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1442923572568283297' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1442923572568283297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1442923572568283297'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/javascript-expando.html' title='[JavaScript] expando 屬性的定義與使用'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1761158142232148448</id><published>2009-02-16T11:42:00.002+08:00</published><updated>2011-05-27T11:47:54.851+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>[SQL Server] 減少 Transaction Log 所佔的硬碟容量</title><content type='html'>今天同事在問，之前也沒做過，所以上網找了一下資料，發現以下兩個不錯的連結說明：&lt;br /&gt;&lt;br /&gt;&lt;a href="http://brad640105.blogspot.com/2008/06/transaction-log.html" target="_blank"&gt;Brad's MIS Note: 交易紀錄檔 Transaction Log 管理&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.souzz.net/big5.php?/html/database/SYBASE/1446.html" target="_blank"&gt;數據庫日常維護(參考)&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1761158142232148448?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1761158142232148448/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1761158142232148448' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1761158142232148448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1761158142232148448'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/sql-server-transaction-log.html' title='[SQL Server] 減少 Transaction Log 所佔的硬碟容量'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8843859830282847263</id><published>2009-02-12T14:15:00.003+08:00</published><updated>2009-02-12T14:19:18.301+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='WebDevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>[jQuery] jQuery + AJAX</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;b&gt;AJAX&lt;br /&gt;&lt;/b&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;AJAX，這個技術是透過 JavaScript 中的 XMLHttpRequest 物件去呼叫後端 server code 並動態改變前端的網頁，讓網頁不需要 refresh。&lt;br /&gt;&lt;br /&gt;AJAX 的技術並不複雜，大概掌握幾個重點即可：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;XMLHttpRequest 物件將資料傳遞到後端 server 的方式，可分為 &lt;b style="color: rgb(255, 0, 0);"&gt;POST &lt;/b&gt;與 &lt;b style="color: rgb(255, 0, 0);"&gt;GET&lt;/b&gt;。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;從 server 回傳的資料可以是 &lt;b style="color: rgb(255, 0, 0);"&gt;plain text&lt;/b&gt; 或是 &lt;b style="color: rgb(255, 0, 0);"&gt;XML&lt;/b&gt;。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;前端網頁 DOM 的處理........(這其實跟 AJAX 已經沒有太大關係了)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;b&gt;jQuery 與 AJAX 的搭配&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;直接寫 pure XMLHttpRequest 的程式碼真的太累了，光是 cross browser 的問題就可以搞死人了......不過還好 jQuery 都幫大家處理好啦!&lt;br /&gt;&lt;br /&gt;以下用的範例程式來說明：(&lt;a title="點選此處" target="_blank" href="http://code.twcic.net/jQuery/sample/ajax01.html" id="z_ke"&gt;&lt;/a&gt;&lt;a title="demo" target="_blank" href="http://code.twcic.net/jQuery/sample/ajax01.html" id="v3y3"&gt;demo&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ajax01.html&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;$&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;//取得 button 物件並註冊 click 事件&lt;/span&gt;&lt;br /&gt;  $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#btnAJAX"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 153, 0);"&gt;//取得使用者輸入的值&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/span&gt; intValue = $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#txtValue"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;    &lt;br /&gt;      &lt;span style="color: rgb(0, 153, 0);"&gt;/*  以 POST 的方式送出 request&lt;br /&gt;          傳入參數 : value&lt;br /&gt;          參數值 = intValue&lt;br /&gt;          callback function 為 function(result){...} */&lt;/span&gt;&lt;br /&gt;      $.&lt;span style="color: rgb(0, 102, 0);"&gt;post&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"server01.php"&lt;/span&gt;, &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;value : intValue&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;, &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;result&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;          $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#spnMain"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;html&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"server 端回傳結果 = "&lt;/span&gt; + result&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;      &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;  &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;請輸入整數值，server 會計算其平方值並回傳：&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;input type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text"&lt;/span&gt; id=&lt;span style="color: rgb(51, 102, 204);"&gt;"txtValue"&lt;/span&gt; /&amp;gt; &amp;lt;input type=&lt;span style="color: rgb(51, 102, 204);"&gt;"button"&lt;/span&gt; id=&lt;span style="color: rgb(51, 102, 204);"&gt;"btnAJAX"&lt;/span&gt; value=&lt;span style="color: rgb(51, 102, 204);"&gt;"從 server 端取得結果"&lt;/span&gt; &lt;span style="color: rgb(0, 102, 255);"&gt;/&amp;gt;&amp;lt;p /&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;span id=&lt;span style="color: rgb(51, 102, 204);"&gt;"spnMain"&lt;/span&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;b&gt;server01.php&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="php"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;&amp;lt;?php&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;a href="http://www.php.net/isset"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;isset&lt;/span&gt;&lt;/a&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;$_POST&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"value"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;a href="http://www.php.net/echo"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;$_POST&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"value"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt; * &lt;span style="color: rgb(0, 0, 255);"&gt;$_POST&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;"value"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(177, 177, 0);"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;a href="http://www.php.net/echo"&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;echo&lt;/span&gt;&lt;/a&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;"0"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;b&gt;?&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;從上面的範例可以看出，透過 jQuery 物件的 &lt;a title="post()" target="_blank" href="http://docs.jquery.com/Ajax/jQuery.post#urldatacallbacktype" id="tue7"&gt;post()&lt;/a&gt;  方法就可以直接享受到 AJAX 的好處囉! 當然，也可以用 &lt;a title="get()" target="_blank" href="http://docs.jquery.com/Ajax/jQuery.get#urldatacallbacktype" id="kz.5"&gt;get()&lt;/a&gt;  的方式來達到 AJAX 的效果。&lt;br /&gt;&lt;br /&gt;此外，callback function 的部份比較需要注意的就是參數的傳遞了，在 jQuery 中可以允許使用一般的方式或是 context 的方式傳入參數，以下用範例說明：(&lt;a title="demo" target="_blank" href="http://code.twcic.net/jQuery/sample/ajax02.html" id="p35z"&gt;demo&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ajax02.html&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;//測試函式&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt; testFunc&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;intVal&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"final value is "&lt;/span&gt; + &lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;intVal * &lt;span style="color: rgb(204, 0, 0);"&gt;2&lt;/span&gt; + &lt;span style="color: rgb(204, 0, 0);"&gt;10&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;//end function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;//取得 button 物件並註冊 click 事件&lt;/span&gt;&lt;br /&gt;  $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#btnAJAX"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 153, 0);"&gt;//取得使用者輸入的值&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;var&lt;/b&gt;&lt;/span&gt; intValue = $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#txtValue"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;    &lt;br /&gt;      &lt;span style="color: rgb(0, 153, 0);"&gt;/*  以 POST 的方式送出 request&lt;br /&gt;          傳入參數 : value&lt;br /&gt;          參數值 = intValue&lt;br /&gt;          callback function 為 function(result){...} */&lt;/span&gt;&lt;br /&gt;      $.&lt;span style="color: rgb(0, 102, 0);"&gt;post&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"server.php"&lt;/span&gt;, &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;value : intValue&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;, &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;result&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: rgb(0, 153, 0);"&gt;//直接呼叫 function&lt;/span&gt;&lt;br /&gt;          testFunc&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;result&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;       &lt;br /&gt;          &lt;span style="color: rgb(0, 153, 0);"&gt;//使用 jQuery context 的方式呼叫 function&lt;/span&gt;&lt;br /&gt;          testFunc.&lt;span style="color: rgb(0, 102, 0);"&gt;apply&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;, &lt;span style="color: rgb(102, 204, 102);"&gt;[&lt;/span&gt;result&lt;span style="color: rgb(102, 204, 102);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;      &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;  &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;請輸入整數值，server 會計算其平方值並回傳：&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;input type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text"&lt;/span&gt; id=&lt;span style="color: rgb(51, 102, 204);"&gt;"txtValue"&lt;/span&gt; /&amp;gt; &amp;lt;input type=&lt;span style="color: rgb(51, 102, 204);"&gt;"button"&lt;/span&gt; id=&lt;span style="color: rgb(51, 102, 204);"&gt;"btnAJAX"&lt;/span&gt; value=&lt;span style="color: rgb(51, 102, 204);"&gt;"從 server 端取得結果"&lt;/span&gt; &lt;span style="color: rgb(0, 102, 255);"&gt;/&amp;gt;&amp;lt;p /&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;span id=&lt;span style="color: rgb(51, 102, 204);"&gt;"spnMain"&lt;/span&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="jQuery: Write less, do more - Opera Developer Community" target="_blank" href="http://visualjquery.com/" id="m8ei"&gt;Visual jQuery 1.2.6&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="jQuery: Write less, do more - Opera Developer Community" target="_blank" href="http://dev.opera.com/articles/view/jquery-write-less-do-more/#ajax" id="m8ei"&gt;jQuery: Write less, do more - Opera Developer Community&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="jQuery 學習心得筆記 (4) - Ajax (上) @ 國三還是菜鳥一枚" target="_blank" href="http://blog.ericsk.org/archives/838" id="u2-z"&gt;jQuery 學習心得筆記 (4) - Ajax (上) @ 國三還是菜鳥一枚&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="jQuery 學習心得筆記 (5) - Ajax (下) @ 國三還是菜鳥一枚" target="_blank" href="http://blog.ericsk.org/archives/839" id="f7dg"&gt;jQuery 學習心得筆記 (5) - Ajax (下) @ 國三還是菜鳥一枚&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8843859830282847263?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8843859830282847263/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8843859830282847263' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8843859830282847263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8843859830282847263'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/jquery-jquery-ajax.html' title='[jQuery] jQuery + AJAX'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1332987275456412923</id><published>2009-02-12T10:02:00.004+08:00</published><updated>2009-02-12T16:36:13.161+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='WebDevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>[jQuery] jQuery 初體驗</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;b&gt;第一支 jQuery 程式&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;很久之前就聽過 &lt;a title="jQuery" target="_blank" href="http://jquery.com/" id="aosf"&gt;jQuery&lt;/a&gt; 的大名啦!&lt;br /&gt;&lt;br /&gt;所以來試試看這個 JavaScript Framwork 到底厲害之處在哪裡..........&lt;br /&gt;&lt;br /&gt;之前在查詢 JavaScript framework 的時候就有大概瞭解到，jQuery 的強項在於 DOM 的處理，據用過的人說，jQuery 處理 DOM 可是又快又簡單，是否真的有這麼神奇呢?&lt;br /&gt;&lt;br /&gt;官網 tutorial 中的第一隻程式就有一些 DOM 的簡單應用：&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;$&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;/* 預設按下超連結都會執行以下的效果 */&lt;/span&gt;&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"a"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;event&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"Thanks for visiting!"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;  &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//透過 event 的 preventDefault() 方法，停止原本要做的動作(網頁導向指定頁面)&lt;/span&gt;&lt;br /&gt;     event.&lt;span style="color: rgb(0, 102, 0);"&gt;preventDefault&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;  &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//將此 object 隱藏(有慢慢隱藏的效果)&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;hide&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"slow"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;//幫每一個 hyperlink 都加上 css 效果(對應到上方程式中定義的粗體)&lt;/span&gt;&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"a"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"test"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;/* 由於 jQuery 的 function 都會回傳原本的 query object，因此可以將程式串在一起執行&lt;br /&gt;       因此以下程式執行的工作為：&lt;br /&gt;       1、按下超連結時，搜尋 class 名稱���否為 "clickme"，若���，執行以下工作：&lt;br /&gt;          1.1 顯示 "Thanks for visiting!" 訊息 (上面已經定義過的動作會照樣進行)&lt;br /&gt;       1.2 開始慢慢消失&lt;br /&gt;       1.3 顯示 "you are leaving the site." 訊息&lt;br /&gt;       1.4 由於顯示訊息的關係(花了點時間)，會讓超連結一瞬間消失(其實它���慢慢消失的)&lt;br /&gt;       2、使用 end() 方法，回到開始進行 query 的 document object(原本��� hyperlink object)&lt;br /&gt;       3、按下超連結時，搜尋 class 名稱���否為 "hideme"，若���，執行以下工作：&lt;br /&gt;          3.1 顯示 "Thanks for visiting!" 訊息 (上面已經定義過的動作會照樣進行)&lt;br /&gt;          3.2 開始慢慢消失(這裡不寫 hide 也行，因為上面已經用過)&lt;br /&gt;          3.3 回傳 false&lt;br /&gt;       4、最後又使用 end() 方法，回到開始進行 query 的 document object&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"a"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;filter&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;".clickme"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"you are leaving the site."&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;filter&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;".hideme"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;hide&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;false&lt;/b&gt;&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;style type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/css"&lt;/span&gt;&amp;gt;&lt;br /&gt; a.&lt;span style="color: rgb(0, 102, 0);"&gt;test&lt;/span&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; font-weight: bold; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;"http://jquery.com/"&lt;/span&gt;&amp;gt;jQuery&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;"http://google.com/"&lt;/span&gt; &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;=&lt;span style="color: rgb(51, 102, 204);"&gt;"clickme"&lt;/span&gt;&amp;gt;I give a message when you leave&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;"http://yahoo.com/"&lt;/span&gt; &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;=&lt;span style="color: rgb(51, 102, 204);"&gt;"hideme"&lt;/span&gt;&amp;gt;Click me to hide!&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;"http://microsoft.com"&lt;/span&gt;&amp;gt;I&lt;span style="color: rgb(51, 102, 204);"&gt;'m a normal link&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;Event Regist&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"document is ready!"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;/*  $ 符號代表的意義為 jQuery class&lt;br /&gt;         $("a") 屬於 jQuery selector&lt;br /&gt;         並註冊了 click 的事件(事件的註冊會累計執行) */&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"a"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         &lt;span style="color: rgb(0, 0, 102);"&gt;alert&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"Hello World!"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;/* 透過此種方式進行 event regist&lt;br /&gt;     就不用在每個 element 中撰寫類似「&amp;lt;a href="" onclick="alert('Hello world')"&amp;gt;Link&amp;lt;/a&amp;gt;」的語法了&lt;br /&gt;     這樣最大的優點是：「HTML、JavaScript、CSS 都可以徹底的分離了!」 */&lt;/span&gt;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;   &lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;""&lt;/span&gt;&amp;gt;Link&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;使用 selector $("元素名稱") 選擇特定的 element，並進行 event regist。 (範例中註冊的是 click 事件)&lt;br /&gt;&lt;br /&gt;透過 jQuery 的 event regist 方式，就可以作到將 HTML、JavaScript、CSS 三個徹底分離，讓後續管理更簡單方便。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;Selector 的應用&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//尋找 ID 為 orderedlist 的 element，並增加 css 效果&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#orderedlist"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"red"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//尋找 orderedlist 的 li element，並增加 css 效果&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#orderedlist &amp;gt; li"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"blue"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//尋找 orderlist 中最後一個 li element，並註冊 hover 事件，指定發生的 css 效果&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#orderedlist li:last"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;hover&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;addClass&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"green"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;, &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;removeClass&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"green"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;/* 尋找 ID 為 orderedlist 的 element&lt;br /&gt;     並在其所有的 li element 加上字串&lt;br /&gt;     而「$("#orderedlist").find("li")」的效果等同「$("#orderedlist &amp;gt; li")」*/&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#orderedlist"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;find&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"li"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;each&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;append&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;" BAM! "&lt;/span&gt; + i&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;ol id=&lt;span style="color: rgb(51, 102, 204);"&gt;"orderedlist"&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;First element&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Second element&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Third element&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;ol&gt;&lt;li&gt;使用 css + xpath 結合的方式尋找 element，例如範例中的「&lt;b&gt;$("#orderedlist &amp;gt; li")&lt;/b&gt;」以及「&lt;b&gt;$("#orderedlist li:last")&lt;/b&gt;」&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;使用 &lt;a title="each" target="_blank" href="http://docs.jquery.com/Core/each#callback" id="v-9p"&gt;each&lt;/a&gt; 在每個 element 後方在另外加上字串&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//尋找不包含 ul 的 li element，並指定 css 效果&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"li"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;not&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;":has(ul)"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;css&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"border"&lt;/span&gt;, &lt;span style="color: rgb(51, 102, 204);"&gt;"1px solid black"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;   &lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;ol id=&lt;span style="color: rgb(51, 102, 204);"&gt;"orderedlist"&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;First element&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Second element&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Third element&amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;ol id=&lt;span style="color: rgb(51, 102, 204);"&gt;"orderedlist2"&lt;/span&gt;&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;First element, second list&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Second element, second list&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Third element, second list&amp;lt;/li&amp;gt;&lt;br /&gt; &amp;lt;li&amp;gt;Li &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;with&lt;/b&gt;&lt;/span&gt; child ul&lt;br /&gt;     &amp;lt;ul&amp;gt;&lt;br /&gt;         &amp;lt;li&amp;gt;Child One&amp;lt;/li&amp;gt;&lt;br /&gt;         &amp;lt;li&amp;gt;child two&amp;lt;/li&amp;gt;&lt;br /&gt;     &amp;lt;/ul&amp;gt;&lt;br /&gt; &amp;lt;/li&amp;gt;&lt;br /&gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;ol&gt;&lt;li&gt;透過 &lt;a title="not(expr)" target="_blank" href="http://docs.jquery.com/Traversing/not#expr" id="h:jx"&gt;not(expr)&lt;/a&gt; 與 &lt;a title=":has(selector)" target="_blank" href="http://docs.jquery.com/Selectors/has#selector" id="ohgf"&gt;:has(selector)&lt;/a&gt; 的搭配，取得不包含 ul 的 li element&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;使用 &lt;a title="css(name, value)" target="_blank" href="http://docs.jquery.com/CSS/css#namevalue" id="n7y."&gt;css(name, value)&lt;/a&gt; 指定 css 效果&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; &lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"a[name]"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;css&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"background-color"&lt;/span&gt;, &lt;span style="color: rgb(51, 102, 204);"&gt;"#bbb"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;a href=&lt;span style="color: rgb(51, 102, 204);"&gt;""&lt;/span&gt;&amp;gt;no &lt;span style="color: rgb(0, 0, 102);"&gt;name&lt;/span&gt; attribute&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;p /&amp;gt;&lt;br /&gt;&amp;lt;a &lt;span style="color: rgb(0, 0, 102);"&gt;name&lt;/span&gt;=&lt;span style="color: rgb(51, 102, 204);"&gt;"test"&lt;/span&gt; href=&lt;span style="color: rgb(51, 102, 204);"&gt;""&lt;/span&gt;&amp;gt;has &lt;span style="color: rgb(0, 0, 102);"&gt;name&lt;/span&gt; attribute&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;透過 element[attribute_name] 的方式取得擁有特定 attribute 的元素&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;/*  一連串的動作，說明如下：&lt;br /&gt;     1、尋找 ID 為 FAQ 的 element&lt;br /&gt;     2、尋找該 element 下的 dd element，並將其隱藏&lt;br /&gt;     3、使用 end() 回到 faq element 狀態&lt;br /&gt;     4、繼續尋找 dt element，並進行 event regist&lt;br /&gt;     5、設定 click 後，會讓 dt element 的下一個 element 進行 slideToggle() 的動作  */&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#faq"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;find&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'dd'&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;hide&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;find&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'dt'&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;next&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;slideToggle&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//使用 end() 的優點在於 $("#faq") 僅會發生一次 DOM select&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;   &lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;h3&amp;gt;Bird FAQ - click the questions to show the answers&amp;lt;/h3&amp;gt;&lt;br /&gt; &amp;lt;dl id=&lt;span style="color: rgb(51, 102, 204);"&gt;"faq"&lt;/span&gt;&amp;gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;What shouldn&lt;span style="color: rgb(51, 102, 204);"&gt;'t I do to the bird?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;Never use oils or lotions which contain oils on your bird. They gunk up the feathers,&lt;br /&gt;     and ruin their insulating properties. This means a chilled bird. Never wait out a cat bite--those&lt;br /&gt;     require immediate veterinary attention--a bird can die within two days because a cat'&lt;/span&gt;s mouth &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; so&lt;br /&gt;     filthy and full of bacteria. &lt;span style="color: rgb(0, 102, 0);"&gt;Don&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'t bother with over-the-counter medication. It really doesn'&lt;/span&gt;t work,&lt;br /&gt;     and &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; some cases, may upset the delicate bacterial balance &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; the bird&lt;span style="color: rgb(51, 102, 204);"&gt;'s body, or even worsen the&lt;br /&gt;     situation. Never try to treat a fracture at home.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;My bird is healthy. I don'&lt;/span&gt;t need to go to a vet, &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt; I?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;Schedule a &lt;span style="color: rgb(51, 102, 204);"&gt;"well-bird"&lt;/span&gt; checkup. &lt;span style="color: rgb(0, 102, 0);"&gt;Prevention&lt;/span&gt; &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; the best medicine. &lt;span style="color: rgb(0, 102, 0);"&gt;Even&lt;/span&gt; though the bird might appear outwardly healthy, it may have a low-grade infection or something not so readily apparent. &lt;span style="color: rgb(0, 102, 0);"&gt;Your&lt;/span&gt; bird&lt;span style="color: rgb(51, 102, 204);"&gt;'s health and your peace of mind will be worth it.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;My bird'&lt;/span&gt;s leg &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; being rubbed raw by the leg band. &lt;span style="color: rgb(0, 102, 0);"&gt;Can&lt;/span&gt; I take it off?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;No. &lt;span style="color: rgb(0, 102, 0);"&gt;Don&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'t attempt this, especially if the leg is broken or swollen. The vet will be able&lt;br /&gt;     to remove the band, and deal with whatever injury maybe lurking under the banded area.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;How do I pull a broken blood feather?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;This is probably the most common mishap. The remedy is simple--yank! It'&lt;/span&gt;s most easily done&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;with&lt;/b&gt;&lt;/span&gt; two people. &lt;span style="color: rgb(0, 102, 0);"&gt;One&lt;/span&gt; to restrain the bird and the other to pull the feather. &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;Use&lt;/b&gt;&lt;/span&gt; pliers, or a&lt;br /&gt;     hemostat. &lt;span style="color: rgb(0, 102, 0);"&gt;Tweezers&lt;/span&gt; won&lt;span style="color: rgb(51, 102, 204);"&gt;'t work on primaries. Make certain that the wing bones are firmly supported&lt;br /&gt;     or you can break the wing. Clamp onto the feather and give a sharp tug in the direction of the&lt;br /&gt;     feather. The feather will come out. Next, apply gentle, direct pressure to the follicle where the&lt;br /&gt;     feather was to stop the bleeding. Dab some styptic powder on it, as it will help stop the bleeding&lt;br /&gt;     as well. Let the bird rest. Ask your vet or breeder to demonstrate exactly how to pull a blood&lt;br /&gt;     feather if you'&lt;/span&gt;re apprehensive about doing it.&amp;lt;/dd&amp;gt;&lt;br /&gt; &amp;lt;/dl&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;ol&gt;&lt;li&gt;透過 &lt;a title="next()" target="_blank" href="http://docs.jquery.com/Traversing/next#expr" id="i80o"&gt;next()&lt;/a&gt; 可以取得 next sibling node&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;使用 &lt;a title="end()" target="_blank" href="http://docs.jquery.com/Traversing/end" id="smzg"&gt;end()&lt;/a&gt; 的優點在於 $("#faq") 的 DOM select 動作只會作一次，因此可以增加程式執行效能&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="slideToggle()" target="_blank" href="http://docs.jquery.com/Effects/slideToggle#speedcallback" id="owes"&gt;slideToggle()&lt;/a&gt; 就只是滑動的效果而已，不過官方文件中還可以另外指定 speed 跟 callback function&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre class="javascript"&gt;&amp;lt;html&amp;gt;                                                               &lt;br /&gt;&amp;lt;head&amp;gt;                                                               &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt; src=&lt;span style="color: rgb(51, 102, 204);"&gt;"js/jquery-1.3.1.js"&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;       &lt;br /&gt;&amp;lt;script type=&lt;span style="color: rgb(51, 102, 204);"&gt;"text/javascript"&lt;/span&gt;&amp;gt;                                      &lt;br /&gt;&amp;lt;!--&lt;br /&gt; $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;document&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;ready&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt; &lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;/*  一連串的動作，說明如下：&lt;br /&gt;     1、尋找 ID 為 FAQ 的 element&lt;br /&gt;     2、尋找該 element 下的 dd element，並將其隱藏&lt;br /&gt;     3、使用 end() 回到 faq element 狀態&lt;br /&gt;     4、繼續尋找 dt element，並進行 event regist&lt;br /&gt;     5、設定 click 後，會讓 dt element 的下一個 element 進行 slideToggle() 的動作  */&lt;/span&gt;&lt;br /&gt;     $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;"#faq"&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;find&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'dd'&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;hide&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;find&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'dt'&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;click&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;function&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;{&lt;/span&gt;&lt;br /&gt;         $&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;next&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;.&lt;span style="color: rgb(0, 102, 0);"&gt;slideToggle&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;     &lt;span style="color: rgb(0, 153, 0);"&gt;//使用 end() 的優點在於 $("#faq") 僅會發生一次 DOM select&lt;/span&gt;&lt;br /&gt; &lt;span style="color: rgb(102, 204, 102);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(102, 204, 102);"&gt;)&lt;/span&gt;;&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;   &lt;br /&gt;&lt;br /&gt;&amp;lt;/head&amp;gt;                                                              &lt;br /&gt;&amp;lt;body&amp;gt;                                                               &lt;br /&gt;&amp;lt;h3&amp;gt;Bird FAQ - click the questions to show the answers&amp;lt;/h3&amp;gt;&lt;br /&gt; &amp;lt;dl id=&lt;span style="color: rgb(51, 102, 204);"&gt;"faq"&lt;/span&gt;&amp;gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;What shouldn&lt;span style="color: rgb(51, 102, 204);"&gt;'t I do to the bird?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;Never use oils or lotions which contain oils on your bird. They gunk up the feathers,&lt;br /&gt;     and ruin their insulating properties. This means a chilled bird. Never wait out a cat bite--those&lt;br /&gt;     require immediate veterinary attention--a bird can die within two days because a cat'&lt;/span&gt;s mouth &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; so&lt;br /&gt;     filthy and full of bacteria. &lt;span style="color: rgb(0, 102, 0);"&gt;Don&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'t bother with over-the-counter medication. It really doesn'&lt;/span&gt;t work,&lt;br /&gt;     and &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; some cases, may upset the delicate bacterial balance &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; the bird&lt;span style="color: rgb(51, 102, 204);"&gt;'s body, or even worsen the&lt;br /&gt;     situation. Never try to treat a fracture at home.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;My bird is healthy. I don'&lt;/span&gt;t need to go to a vet, &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;do&lt;/b&gt;&lt;/span&gt; I?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;Schedule a &lt;span style="color: rgb(51, 102, 204);"&gt;"well-bird"&lt;/span&gt; checkup. &lt;span style="color: rgb(0, 102, 0);"&gt;Prevention&lt;/span&gt; &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; the best medicine. &lt;span style="color: rgb(0, 102, 0);"&gt;Even&lt;/span&gt; though the bird might appear outwardly healthy, it may have a low-grade infection or something not so readily apparent. &lt;span style="color: rgb(0, 102, 0);"&gt;Your&lt;/span&gt; bird&lt;span style="color: rgb(51, 102, 204);"&gt;'s health and your peace of mind will be worth it.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;My bird'&lt;/span&gt;s leg &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;is&lt;/b&gt;&lt;/span&gt; being rubbed raw by the leg band. &lt;span style="color: rgb(0, 102, 0);"&gt;Can&lt;/span&gt; I take it off?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;No. &lt;span style="color: rgb(0, 102, 0);"&gt;Don&lt;/span&gt;&lt;span style="color: rgb(51, 102, 204);"&gt;'t attempt this, especially if the leg is broken or swollen. The vet will be able&lt;br /&gt;     to remove the band, and deal with whatever injury maybe lurking under the banded area.&amp;lt;/dd&amp;gt;&lt;br /&gt;&lt;br /&gt;     &amp;lt;dt&amp;gt;How do I pull a broken blood feather?&amp;lt;/dt&amp;gt;&lt;br /&gt;     &amp;lt;dd&amp;gt;This is probably the most common mishap. The remedy is simple--yank! It'&lt;/span&gt;s most easily done&lt;br /&gt;     &lt;span style="color: rgb(0, 0, 102);"&gt;&lt;b&gt;with&lt;/b&gt;&lt;/span&gt; two people. &lt;span style="color: rgb(0, 102, 0);"&gt;One&lt;/span&gt; to restrain the bird and the other to pull the feather. &lt;span style="color: rgb(0, 51, 102);"&gt;&lt;b&gt;Use&lt;/b&gt;&lt;/span&gt; pliers, or a&lt;br /&gt;     hemostat. &lt;span style="color: rgb(0, 102, 0);"&gt;Tweezers&lt;/span&gt; won&lt;span style="color: rgb(51, 102, 204);"&gt;'t work on primaries. Make certain that the wing bones are firmly supported&lt;br /&gt;     or you can break the wing. Clamp onto the feather and give a sharp tug in the direction of the&lt;br /&gt;     feather. The feather will come out. Next, apply gentle, direct pressure to the follicle where the&lt;br /&gt;     feather was to stop the bleeding. Dab some styptic powder on it, as it will help stop the bleeding&lt;br /&gt;     as well. Let the bird rest. Ask your vet or breeder to demonstrate exactly how to pull a blood&lt;br /&gt;     feather if you'&lt;/span&gt;re apprehensive about doing it.&amp;lt;/dd&amp;gt;&lt;br /&gt; &amp;lt;/dl&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;                                                              &lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;ol&gt;&lt;li&gt;透過 &lt;a title="parents(expr)" target="_blank" href="http://docs.jquery.com/Traversing/parents#expr" id="sxy:"&gt;parents(expr)&lt;/a&gt;  取得父節點，並指定 css 效果。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Tutorials:How jQuery Works - jQuery JavaScript Library" target="_blank" href="http://docs.jquery.com/Tutorials:How_jQuery_Works" id="mijp"&gt;Tutorials:How jQuery Works - jQuery JavaScript Library&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Tutorials:Getting Started with jQuery - jQuery JavaScript Library" target="_blank" href="http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery" id="bpw7"&gt;Tutorials:Getting Started with jQuery - jQuery JavaScript Library&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jsgears.com/thread-63-1-1.html" target="_blank"&gt;jQuery 教學 - 基礎篇 - JavaScript 教學、心得分享 - jsGears.com 技術論壇 - AJAX, JavaScript, jQuery, 討論, 教學, 範例 - Powered by Discuz!&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1332987275456412923?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1332987275456412923/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1332987275456412923' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1332987275456412923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1332987275456412923'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/jquery-jquery_8409.html' title='[jQuery] jQuery 初體驗'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7934473048813624709</id><published>2009-02-10T17:10:00.003+08:00</published><updated>2011-05-27T11:51:00.369+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] Broadcasting &amp; Multicasting</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;b&gt;前言&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;IP address 有三種，分別是：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;unicast&lt;/b&gt;&lt;br /&gt;此即為一般的 IP address，傳送者與接收者是一對一的關係。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;broadcast&lt;/b&gt;&lt;br /&gt;當要將訊息發布給同網段中所有的電腦時，就將訊息送給 broadcast IP address，這樣一來所有的電腦都會將訊息接收過去。使用此特性的協定有 ARP、RARP....等等。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;multicast&lt;/b&gt;&lt;br /&gt;此種也是類似 broadcast，但接收端僅為特定的群組，並非全部電腦都包含在內。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;其中 &lt;b style="color: rgb(255, 0, 0);"&gt;broadcase 與 multicase 都必須仰賴 UDP 協定&lt;/b&gt;，原因是因為使用 TCP 必須先進行 3-way Handshake 以進行兩端點間的連線，並不適合用於此情境中。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;Broadcasting&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;broadcast 是將資料傳送到網路中所有的電腦的一種方式，一共可以分為四種：(&lt;a title="資料來源" target="_blank" href="http://www.iicm.org.tw/communication/c1_2/page05.html" id="ldez"&gt;資料來源&lt;/a&gt;)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;有限廣播 (Limited Broadcast)&lt;/b&gt;&lt;br /&gt;只有目前所在的區域網路 (LAN) 上作廣播，其IP的地址格式為255.255.255.255。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;網路取向廣播 (Net-directed Broadcast)&lt;/b&gt;&lt;br /&gt;在某特定 (指定) 的網路作廣播，例如向某一類別為A (Class A) 的網路廣播，其IP地址格式為netid.255.255.255。&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;子網路取向廣播 (Subnet-directed Broadcast)&lt;/b&gt;&lt;br /&gt;針對某等級(class) 中的某子網路 (Subnetwork) 作廣播。以類別B的網路來看，若其子網路遮罩 (subnet mask) 為255.255.255.0，而IP地址為140.116.46.255，則是表示將資料廣播到類別B的網路140.116.中的子網路46上，而最後一個255則是代表廣播的意思。&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;全子網路取向廣播&lt;/b&gt;&lt;b&gt; (All-subnets-directed Broadcast)&lt;/b&gt;&lt;br /&gt;針對某一等級中所有的子網路皆作廣播。此種廣播方式必須與路由器 (router) 的子網路遮罩配合。例如有一類別B的子網路遮罩為255.255.255.0，則若有一IP地址為140.116.255.255時，則表示將資料廣播到類別B的網路140.116中的所有子網路上。在實際的網路架構中，歸屬於某一類別網路的所有子網路，可能位在不同路由器 (router) 的不同輸出入埠上(port)，因此藉由子網路遮罩，路由器可以將資料傳送到所屬的所有子網路上進行廣播&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;Multicasting&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;IP Multicasting 是將資料傳送給某一特定群體 (Group) 的所有成員 (members)，而屬於同一群體的各個成員可能是散佈在各個不同的網路上。&lt;br /&gt;&lt;br /&gt;接著用一張圖來說明 multicasting 的 IP address 格式：&lt;div id="r40i" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 513px; height: 50px;" src="http://docs.google.com/File?id=ddzmw8vs_491f4m9vhs4_b" /&gt;&lt;/div&gt;&lt;br /&gt;從上圖可以知道，multicasting IP address 屬於 class D，其範圍介於「&lt;b style="color: rgb(0, 0, 255);"&gt;224.0.0.0&lt;/b&gt; ~ &lt;b style="color: rgb(0, 0, 255);"&gt;239.255.255.255&lt;/b&gt;」之間&lt;br /&gt;&lt;br /&gt;在 &lt;a title="RFC 1112" target="_blank" href="http://www.apps.ietf.org/rfc/rfc1112.html" id="vryo"&gt;RFC 1112&lt;/a&gt; 定義了 IP multicast 的標準,它的特性之一是可送出一份 IP datagram 到 LAN 或 WAN 上，只要對這份 datagram 有興趣的使用者加入此「&lt;b style="color: rgb(255, 0, 0);"&gt;group address&lt;/b&gt;」(如何加入呢? 只要設定要擷取特定 multicasting IP address 的資料，就表示加入此 group 了；若是有其他認證機制則另當別論)，就可收到這份 datagram。Multicasting 是一種 push 的技術，server 送出資料而 client 不用發出 request。&lt;br /&gt;&lt;br /&gt;而 router 也要判斷所連結的網段中是否有加入特定 multicasting group 的電腦，來決定是否繼續傳送 multicasting 的訊息，這裡面運作的機制，稱為 &lt;b style="color: rgb(255, 0, 0);"&gt;IGMP&lt;/b&gt;(Internet Group Management Protocol)。&lt;br /&gt;&lt;br /&gt;在目前還是有許多地方會應用到，最常用的大概就屬於視訊會議這一類的應用了。&lt;br /&gt;&lt;br /&gt;然而，IANA 預先定義了幾個 well-known 的 multicasting IP address(就像 well-known port number 一樣)，在使用上就必須要避開這些 IP，例如：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;224.0.0.1&lt;/b&gt; (子網路中所有的系統)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;224.0.0.2&lt;/b&gt; (子網路中所有的 router)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;224.0.1.1&lt;/b&gt; (NTP；Netowork Time Protocol)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;224.0.0.9&lt;/b&gt; (RIP-2)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;當然不只以上這些，而若要查詢最新的清單，可以查詢 RFC 文件。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="unicast, multicast, broadcast :: 樂咖黑電腦學習網 SEO Google Apps" target="_blank" href="http://www.hoyo.idv.tw/hoyoweb/document/view.php?sid=109&amp;amp;author=hoyo&amp;amp;status=view" id="ihyf"&gt;unicast, multicast, broadcast :: 樂咖黑電腦學習網 SEO Google Apps&lt;/a&gt;&lt;a title="Internet上的多媒體群體廣播架構" target="_blank" href="http://www.iicm.org.tw/communication/c1_2/page05.html" id="tmad"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Internet上的多媒體群體廣播架構" target="_blank" href="http://www.iicm.org.tw/communication/c1_2/page05.html" id="tmad"&gt;Internet上的多媒體群體廣播架構&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7934473048813624709?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7934473048813624709/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7934473048813624709' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7934473048813624709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7934473048813624709'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/tcpip-illustrated-broadcasting.html' title='[TCP/IP Illustrated] Broadcasting &amp;amp; Multicasting'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7500263967682953332</id><published>2009-02-10T09:18:00.003+08:00</published><updated>2011-05-27T11:47:54.852+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[Oracle] 網路學習資源</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;TableSpace&lt;br&gt;&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;a title="TableSpace 介紹" target="_blank" href="http://mis.im.tku.edu.tw/%7Exman13a/oracle/tablespace/ora_1.htm" id="k2o:"&gt;TableSpace 介紹&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a title="Oracle TableSpace 表空間 @ 貓熊落網 :: 痞客邦 PIXNET ::" target="_blank" href="http://horace1123.pixnet.net/blog/post/26534596" id="kqpi"&gt;Oracle TableSpace 表空間 @ 貓熊落網 :: 痞客邦 PIXNET ::&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a title="Create tablespace in Oracle" target="_blank" href="http://www.adp-gmbh.ch/ora/sql/create_tablespace.html" id="o658"&gt;Create tablespace in Oracle&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;&lt;br&gt;Import &amp;amp; Export&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Oracle export and import - Oracle Wiki" target="_blank" href="http://wiki.oracle.com/page/Oracle+export+and+import+?t=anon" id="agcn"&gt;Oracle export and import - Oracle Wiki&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a title="[ 永遠的UNIX &amp;gt; oracle Export and Import 簡介 ]" target="_blank" href="http://fanqiang.chinaunix.net/a2/b2/20010514/08280050_b.html" id="qjsv"&gt;[ 永遠的UNIX &amp;gt; oracle Export and Import 簡介 ]&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a title="exp and imp in Oracle" target="_blank" href="http://www.adp-gmbh.ch/ora/admin/imp_exp.html" id="ztlc"&gt;exp and imp in Oracle&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;Performance Tunning&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Oracle performance tuning with indexes" target="_blank" href="http://www.dba-oracle.com/art_9i_indexing.htm" id="zes4"&gt;Oracle performance tuning with indexes&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;SQL 語法應用&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="JavaWorld@TW Java論壇 - 實現 Oracle 上的分頁顯示" target="_blank" href="http://www.javaworld.com.tw/jute/post/view?bid=21&amp;amp;id=52022&amp;amp;sty=1&amp;amp;tpg=1&amp;amp;age=-1" id="zkcw"&gt;JavaWorld@TW Java論壇 - 實現 Oracle 上的分頁顯示&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;未分類&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;a title="Oracle 開發筆記" target="_blank" href="http://blog.miniasp.com/post/2007/10/Oracle-Development-Note.aspx" id="dkoz"&gt;Oracle 開發筆記&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7500263967682953332?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7500263967682953332/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7500263967682953332' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7500263967682953332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7500263967682953332'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/oracle.html' title='[Oracle] 網路學習資源'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3436839637161050858</id><published>2009-02-09T17:37:00.002+08:00</published><updated>2011-05-27T11:51:00.370+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] UDP (User Datagram Protocol)</title><content type='html'>&lt;span style="font-size:180%;"&gt;&lt;b&gt;前言&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;不同於 TCP(stream-oriented，每個 IP datagram 中的資料都有其關聯) 協定，UDP 屬於不可靠的協定，因此並無法保證封包一定可以到達目的地(這表示即使封包沒到達目的地，發送端也不會收到任何通知)。&lt;br /&gt;&lt;br /&gt;以下為 UDP datagram 是如何封裝在 IP datagram 中：&lt;div id="ayru" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 512px; height: 188px;" src="http://docs.google.com/File?id=ddzmw8vs_484gfnmz6cq_b" /&gt;&lt;/div&gt;&lt;br /&gt;由於 UDP 協定必須依靠 IP 協定將資料傳送出去，因此在 UDP datagram 外面還要另外加上 IP datagram。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;UDP Header&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;雖然 UDP 是種不可靠的協定，但相對於 TCP 單純的多，以下是 UDP Header 的內容：&lt;div id="fnr4" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 505px; height: 183px;" src="http://docs.google.com/File?id=ddzmw8vs_485gwgqgxfx_b" /&gt;&lt;/div&gt;&lt;br /&gt;其中比較需要說明的為 UDP length 的部份，而此 length 指的是整個 UDP header 的長度，最少為 8，而從圖中就可以看出，當 length = 8，表示 data 的部份為 0 byte。&lt;br /&gt;&lt;br /&gt;而 checksum 的欄位，可以作為驗證資料正確與否來用，但接收端驗證後，若即使有資料錯誤的情況發生，也只會直接丟棄封包而不會通知傳送端，因此有些網路設備並沒有實作或是開啟驗證 checksum 的功能。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;IP Fragmentation&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;要瞭解 IP 是如何將封包拆開再結合之前，必須先看看 IP header 的內容：&lt;div id="ucf7" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 505px; height: 328px;" src="http://docs.google.com/File?id=ddzmw8vs_486cf9m9cdw_b" /&gt;&lt;/div&gt;當資料量過大時，IP 會自動將資料拆開，分成多個 datagram 進行傳送。&lt;br /&gt;&lt;br /&gt;其中將資料拆開成多個 datagram 的工作在傳送段電腦完成；而將多個 datagram 組合成原本的資料，則是接收段電腦的工作。&lt;br /&gt;&lt;br /&gt;而在 IP header 中用來控制資料拆開與組合的資訊，即為 identification、flag、fragmentation offset 三個欄位。&lt;br /&gt;&lt;br /&gt;此外，若是封包在傳遞的過程中遺失了應該要怎辦? 答案就是：「&lt;b style="color: rgb(255, 0, 0);"&gt;全部重送一次&lt;/b&gt;」。&lt;br /&gt;&lt;br /&gt;但 IP 沒有可以判斷傳送是否發生錯誤的機制，因此必須仰賴上一層的 protocol(例如：TCP) 來處理，而 UDP 沒有此種驗證機制，因此若是有需求，就必須在 UDP application 中有提供才行。&lt;br /&gt;&lt;br /&gt;那到底將資料拆成多個封包後會變得如何呢? 以下有圖可以說明：&lt;div id="regu" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 516px; height: 232px;" src="http://docs.google.com/File?id=ddzmw8vs_487hdxnmfgv_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;UDP datagram 可以到多大?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;理論上，每一個 UDP datagram 最大可以到 65535 bytes(20 bytes IP header + 8 bytes UDP header + 63307 bytes data)，但實際上，由於 socket API 或是 OS kernel 的限制，有時候並無法使用這麼大的 UDP datagram 進行傳送。&lt;br /&gt;&lt;br /&gt;而實際應用上，其實也沒用到如此大的 UDP datagram，舉例來說：&lt;br /&gt;&lt;br /&gt;NFS：使用大小為 8192 bytes 的 UDP datagram&lt;br /&gt;&lt;br /&gt;DNS、TFTP、BOOTP、SNMP：都使用小於 512 bytes 的 UDP datagram&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;與 UDP 協定相關的錯誤&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;ICMP Unreachable Error (Fragmentation Required)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;當封包大小超過 MTU 時，就必須將封包拆開了，但此時如果 IP header 中的 DF(don't fragment) flag 若是被啟用，就會發生 ICMP Unreachable Error。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;ICMP Source Quench Error&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;此種錯誤發生在接收端的 buffer 又已經滿了，且來不及處理快速傳入的 UDP datagram 時。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;基本上，不一定每個接收端發生此種錯誤時，都會處理 ICMP Source Quench Error 訊息給傳送端，這必須要端看接收端的實作情況。(有些會因為協定是 UDP 而忽略，TCP 則會處理)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3436839637161050858?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3436839637161050858/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3436839637161050858' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3436839637161050858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3436839637161050858'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/02/tcpip-illustrated-udp-user-datagram.html' title='[TCP/IP Illustrated] UDP (User Datagram Protocol)'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3806534122450048839</id><published>2009-01-31T15:43:00.004+08:00</published><updated>2009-01-31T15:53:18.928+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='BASH'/><title type='text'>在 Windows 中編輯 Linux Shell Script 的問題</title><content type='html'>最近開始練習 Linux shell script，想說用 Windows 上的編輯器來編輯&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;卻發現程式一直都無法正確執行&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;後來網路上找到資料，原來是 &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Windows 與 Linux 的換行字元不同&lt;/span&gt;&lt;/span&gt;所導致.......&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;這時候就必須要修改一下編輯器的設定了!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;以 MadEdit 為例：&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://lh3.ggpht.com/_-MI_81GSZ2I/SYQBJGDGj8I/AAAAAAAABic/3Nj5ub5Hl_s/s800/bash.PNG" style="cursor:pointer; cursor:hand;width: 661px; height: 319px;" border="0" alt="" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;將換行字元改為 Unix，程式就可以正常執行啦! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;參考資料&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.pczone.com.tw/vbb3/archive/t-135900.html" target="_blank"&gt;linux script 用記事本等編輯過就無法 run 問題 [論壇存檔] - PCZONE 討論區&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3806534122450048839?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3806534122450048839/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3806534122450048839' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3806534122450048839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3806534122450048839'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/windows-linux-shell-script.html' title='在 Windows 中編輯 Linux Shell Script 的問題'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_-MI_81GSZ2I/SYQBJGDGj8I/AAAAAAAABic/3Nj5ub5Hl_s/s72-c/bash.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7989736987698063792</id><published>2009-01-23T13:19:00.002+08:00</published><updated>2011-05-27T11:51:00.372+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] Dynamic Routing Protocols</title><content type='html'>&lt;b&gt;&lt;span style="font-size:180%;"&gt;      Dynamic Routing&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;相鄰的 router 之間互相交換網段資訊、連線資訊 ... 等資訊，稱為 dynamic routing，而在 router 上處理這一類工作的 process，就稱為 routing daemon。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;routing protocol  還可以根據是否在同一個 AS(Autonomous System) 中來分類，分別是：&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;IGP (Interior Gateway Protocol)&lt;/b&gt;&lt;br /&gt;包含 RIP(Routing Information Protocol)、EIGRP、OSPF(Open Shortest Path First Protocol)、IS-IS ... 等等。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;EGP (Exterior Gateway Protocol)&lt;/b&gt;&lt;br /&gt;包含 EGP、BGP(Border Gateway Protocol) ... 等等。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span style="font-size:180%;"&gt;Routing Information Protocol&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;RIP message 是包在 UDP datagram 中傳遞的，以下是傳遞 RIP 訊息的 UDP datagram 格式：&lt;br /&gt;&lt;div id="dftr" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 510px; height: 187px;" src="http://docs.google.com/File?id=ddzmw8vs_478ffwmdbq2_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;接著是 RIP message 本身的格式：&lt;br /&gt;&lt;div id="i8.m" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 506px; height: 329px;" src="http://docs.google.com/File?id=ddzmw8vs_479g6r2g5gb_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;其中 RIP message 有幾個部份需要注意的：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;command&lt;/b&gt;&lt;br /&gt;1 = request&lt;br /&gt;2 = reply&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;version&lt;/b&gt;&lt;br /&gt;是版本不同而不同，RIP = 1，RIPv2 = 2。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;address family&lt;/b&gt;&lt;br /&gt;此欄位的值永遠為 2，而其他框起來的部份(共 20 bytes)則共同組成一個 IP address 與 metric 資訊。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;一個 RIP 訊息最多就僅能帶 25 個 IP address 與 metric 資訊。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;運作方式&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;RIP 所使用的是 UDP port 520，運作的流程如下：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Initialization&lt;/b&gt;&lt;br /&gt;首先會偵測 router 上的介面是否啟用，接著會從啟用的介面送出 request 封包，請求其他 router 將其完整的 routing table 資訊送過來。&lt;br /&gt;而 request 封包中的 command = 1，address family = 0，metric = 16。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Request received&lt;/b&gt;&lt;br /&gt;router 接收到 request 的封包後，回傳 routing table 資訊給請求者；或是根據封包中所請求的位址給予相對應的 routing 資訊。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Response received&lt;/b&gt;&lt;br /&gt;請求者收到回應，更新 routing table。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Regular routing updates&lt;/b&gt;&lt;br /&gt;接著 router 每 30 秒會將自己的 routing table 資訊送給相鄰的 router。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Triggered updates&lt;/b&gt;&lt;br /&gt;當設定有改變時，就可以發送訊息給鄰近的 router 進行修改。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;每個 router 都有其 timeout 的預設值，以三分鐘為例，就表示有 6 次 router advertisement message 沒有收到，因此此時會將 metric 設定為 16，表示此 router 已經不存在，將其刪除。&lt;br /&gt;&lt;br /&gt;但沒辦法避免的，使用 RIP 的確會發生 routing table 更新延遲而發生網路不夠穩定的情況。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;Metric 的意義&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;metric 在 RIP 是用來紀錄封包傳遞時，會經過的 router 次數(hop count)，而直接連接網路介面的 hop count 為 1，以下用圖來說明：&lt;br /&gt;&lt;div id="d1n4" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 519px; height: 208px;" src="http://docs.google.com/File?id=ddzmw8vs_480hkrxvvhr_b" /&gt;&lt;/div&gt;若是 R1 要到 N2，metric = 1&lt;br /&gt;若是 R1 要到 N3，metric = 2&lt;br /&gt;若是 R2 要到 N2，metric = 1&lt;br /&gt;若是 R2 要到 N1，metric = 2&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:130%;" &gt;&lt;b&gt;RIP 的問題所在&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;從上面運作的原理，其實就可以大概推測出一些問題的端倪了，大概有以下幾點：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;hop count 最大是 15，這到 internet 上就不是那麼適用了。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;RIP 無法處理 subnet 的定址資訊。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;不論是 router 故障或是從故障中復原，要讓網路上的其他 router 知道以更新 routing table，需要花過多的時間。&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;RIP version 2&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;基本上 RIPv2 並沒有改變原先 RIP 運作的模式，而是將原本在 RIP message 中沒有用到的欄位拿來使用而已，以下是 RIPv2 message 的格式：&lt;br /&gt;&lt;div id="kyqq" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 510px; height: 329px;" src="http://docs.google.com/File?id=ddzmw8vs_481c84tvjgz_b" /&gt;&lt;/div&gt;不同於 RIP 的欄位說明如下：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;routing domain&lt;/b&gt;&lt;br /&gt;辨識此封包屬於哪個 routing daemon(儲存 process number) 之用，因此表示可以同時有多個 routing daemon 同時處理 RIPv2 的封包。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;route tag&lt;/b&gt;&lt;br /&gt;用來支援 EGP 之用，儲存 AS(Autonomous System) number。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;subnet mask&lt;/b&gt;&lt;br /&gt;對應上面的 IP address，以支援 subnet 的處理。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;另外要提的是，RIPv2 還支援了簡單的認證功能，只要 address family 設定為 0xFFFFF，且 route tag 的值為 2，往下的 16 個 bits 就是儲存明文密碼的地方。&lt;br /&gt;&lt;br /&gt;不僅如此，RIPv2 還支援 multicast，如此一來就不用使用 broadcast 來減少網路流量了!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;OSPF (Open Shortest Path First)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;相較於 RIP，OSPF 是較新的 routing protocol，克服了 RIP 的許多限制，其中 OSPF Ver.2 定義在 &lt;a title="RFC 1247" href="http://www.ietf.org/rfc/rfc1247.txt" id="b0p4"&gt;RFC 1247&lt;/a&gt; 中。&lt;br /&gt;&lt;br /&gt;RIP 屬於距離向量(distance-vector)協定，而 OSPF 屬於鏈路狀態(link-state)協定；差別在於 link-state protocol 中，router 之間不互相交換距離(這裡指的是 hop count)資訊，而是主動偵測周遭 router 的連線狀態(包含實際的距離、頻寬 ... 等資訊)，接著將蒐集到的資訊傳送給同一個 AS 中的所有 router，每個 router 蒐集來自各方的資訊後，再將這些資訊組合而成 routing table。&lt;br /&gt;&lt;br /&gt;其中最重要的是，當網路上有 router 發生問題而無法提供正常服務時，比起 RIP，使用 OSPF 可以大幅降低收斂(亦即重新發送訊息以組合成可以正常提供服務的 routing table)的時間。&lt;br /&gt;&lt;br /&gt;之前提到 RIP 是使用 UDP port 520，而 OSPF 則是直接使用 IP 協定。&lt;br /&gt;&lt;br /&gt;由於 OSPF 屬於 link-state protocol，因此也較 RIP 多了以下的優點：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;可以針對不同的路徑計算出 IP type-of-service，因此在 routing table 中可以針對同一個目的地有多個選擇。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;每個網路介面都會給予一個值，其計算的基準在於 throughput、round-trip time、可靠度 .... 等等。每個 IP type-of-service 都可以賦予一個值。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;當到目的地的封包有多條路徑可以選擇，且每條路徑成本相同時，OSPF 會自動將流量分散從不同的路徑傳遞，以求達到負載平衡的效果。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;點對點之間的連線網路介面不需要 IP address。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;router 之間訊息的傳輸使用 multicast 而非 broadcast，減少整體的網路流量。&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;而現在 routing protocol 幾乎都改用 OSPF 囉!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;BGP (Border Gateway Protocol)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;BGP 是 EGP 的一種，用來在 internet 中讓 AS 之間交換 routing 資訊之用，目前 BGP Ver. 4 的詳細規則可以查詢 &lt;a title="RFC 1771" target="_blank" href="http://www.ietf.org/rfc/rfc1771.txt" id="swyy"&gt;RFC 1771&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;不同 AS 之間會透過 BGP 傳遞包含 AS 的完整 routing 路徑表資訊，藉由組合這些 routing 資訊來形成一個完整的 internet routing 資訊，並避免掉可能發生的 routing loop。&lt;br /&gt;&lt;br /&gt;不同於 RIP(UDP port 520) 與 OSPF(IP)，BGP 系統間的溝通是透過 TCP 協定來交換 routing table 的資訊；此外，BGP 還會定期送出 keepalive 的訊息，用來確定周遭的 AS 是否可以正常提供 routing 的服務，以便當 AS 有問題時，可以縮短收斂的時間。&lt;br /&gt;&lt;br /&gt;而 BGP 的設計上，還可以讓 AS 的管理員自訂設定規則，亦即 BGP 可以允許轉換為 policy-based routing，因此也讓管理者有更大的空間可以發揮與利用。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;CIDR (Classless Interdomain Routing)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;CIDR 應該是不能算是 protocol，而是一種技術(或是功能)。&lt;br /&gt;&lt;br /&gt;怎麼說呢? 這是由於 B class 的網段過於龐大，256 * 256 台主機，如果不切割網段會造成可怕的 broadcast storm，因此解決方式就是切成 C class。&lt;br /&gt;&lt;br /&gt;但是切成 C class 卻衍生出了另一個問題：&lt;b style="color: rgb(255, 0, 0);"&gt;每個 network 之間都必須要有 router&lt;/b&gt;。&lt;br /&gt;&lt;br /&gt;這可是相當麻煩且耗費成本的事情阿，而且 routing table 的數量也會一下子暴增很多；因此 CIDR 就是用來解決這個問題所衍生出來的技術。&lt;br /&gt;&lt;br /&gt;而若是僅按照 Class A B C 去切割網路，其實問題是相當多的，例如：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;浪費 IP address&lt;/b&gt;&lt;br /&gt;使用 A class、B class 的組織不見得用的到這麼多 IP；使用 C class 的組織有可能 IP 數量不夠用；多切割一個網段就必須要多浪費兩個 IP(Network ID &amp;amp; Broadcast)。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;無法符合實際需求&lt;/b&gt;&lt;br /&gt;大部分組織可能會遇到 C class 不夠用，B class 卻太多的情況，僅切成 class A B C 並不符合實際的需求。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;CIDR 使用 7~32 可變換長度的 Network ID 來取代原本 Class A B C 長度為的 8 16 24 的 Network ID，因此 host 範圍可以從 32 ~ 約 50000 個!&lt;br /&gt;&lt;br /&gt;從上面的敘述可以瞭解到，其實 CIDR 的功能就是「&lt;b style="color: rgb(255, 0, 0);"&gt;將多個小網段組成一個較大的網段&lt;/b&gt;」，如此一來 router 所維護的 routing table entry 就可以大大地減少，也因此可以提昇 router 運作的效能。&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="傳統RIP協議--RIP協議的報文格式" target="_blank" href="http://www.souzz.net/big5.php?/Cisco/4/2/100V343R007.html" id="vnf:"&gt;傳統RIP協議--RIP協議的報文格式&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="靜態與動態路由" target="_blank" href="http://www.google.com.tw/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=5&amp;amp;url=http%3A%2F%2Fmail.en.wfc.edu.tw%2Fmcsau_lesson%2Ftcpip%2520%25A7%25EB%25BCv%25A4%25F9%2F%25B2%25C409%25B3%25B9.ppt&amp;amp;ei=BG11Sbz-BKb2swLLqe2HBw&amp;amp;usg=AFQjCNHDxrh5IR2DJtSElVtzLk2Y1vgpJA&amp;amp;sig2=MzLkChQ8MU5_K6szC3Qqiw" id="u7o2"&gt;靜態與動態路由&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="TKWU - Link state or Distance Vector?" href="http://www.tkwu.net/index.php?option=com_content&amp;amp;task=view&amp;amp;id=61&amp;amp;Itemid=42" id="iz57"&gt;TKWU - Link state or Distance Vector?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="OSPF路由協定簡介" href="http://members.tripod.com/khchu/doc/ospf/ospf.htm" id="lhdf"&gt;OSPF路由協定簡介&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="DD馬 's Blog - CIDR與VLSM" target="_blank" href="http://www.wretch.cc/blog/chuchiming/15105808" id="j43r"&gt;DD馬 's Blog - CIDR與VLSM&lt;br /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="CIDR - Allwiki" target="_blank" href="http://www.allwiki.com/index.php?title=CIDR&amp;amp;variant=zh-tw" id="s4f4"&gt;CIDR - Allwiki&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7989736987698063792?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7989736987698063792/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7989736987698063792' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7989736987698063792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7989736987698063792'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/tcpip-illustrated-dynamic-routing.html' title='[TCP/IP Illustrated] Dynamic Routing Protocols'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4161238998986857825</id><published>2009-01-22T14:50:00.002+08:00</published><updated>2011-05-27T11:47:54.853+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] Trigger - 「:NEW」的使用</title><content type='html'>今天試寫一支 trigger，目的是要讓每一列的 action 欄位更新為 1 時，自動塞入日期與時間的資料，第一次用到「&lt;b style="color: rgb(255, 0, 0);"&gt;:new&lt;/b&gt;」，因此記錄一下。&lt;br /&gt;&lt;br /&gt;以下是程式碼：&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;create&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;or&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;replace&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;trigger&lt;/span&gt; tri_fill_datetime_to_message&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--只有在更新資料後才需要加入日期時間資訊&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;before&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;update&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;on&lt;/span&gt;  mytable&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;each&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;row&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;begin&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--當 action 更新的值為 1 時，在執行以下動作&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;if&lt;/span&gt; :new&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;action&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;then&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(105, 105, 105);"&gt;--設定新資料的日期時間資訊&lt;/span&gt;&lt;br /&gt;  :new&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;log_date :&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;to_char&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;sysdate&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'YYYYMMDD'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;  :new&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;log_time :&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;to_char&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;sysdate&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'HH24MISS'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;  :new&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;log_datetime :&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(187, 121, 119); font-weight: bold;"&gt;sysdate&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;end if&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;end&lt;/span&gt; tri_fill_datetime_to_message&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Coding Triggers" target="_blank" href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm" id="v-jj"&gt;Coding Triggers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="比较 oracle 和 SQL Server 的 Trigger - Oracle开发 - ITPUB论坛 - 皓辰传媒旗下专业技术社区" target="_blank" href="http://www.itpub.net/thread-72431-1-1.html" id="oxb:"&gt;比较 oracle 和 SQL Server 的 Trigger - Oracle开发 - ITPUB论坛 - 皓辰传媒旗下专业技术社区&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Before, after, each row and table level triggers [Oracle]" target="_blank" href="http://www.adp-gmbh.ch/ora/sql/trigger/before_after_each_row.html" id="pgq."&gt;Before, after, each row and table level triggers [Oracle]&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4161238998986857825?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4161238998986857825/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4161238998986857825' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4161238998986857825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4161238998986857825'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/oracle-trigger-new.html' title='[Oracle] Trigger - 「:NEW」的使用'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6253731630480360877</id><published>2009-01-19T16:34:00.002+08:00</published><updated>2011-05-27T11:51:00.373+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] IP Routing</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;IP 在 TCP/IP protocol suit 中是非常重要的一個協定，有多重要呢? 以下用一張圖來簡單說明 IP 所負責的事情：&lt;br /&gt;&lt;div id="n7fv" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 507px; height: 390px;" src="http://docs.google.com/File?id=ddzmw8vs_4723jxjfzw5_b" /&gt;&lt;/div&gt;&lt;br /&gt;在圖中的 routing table 是最常被 IP 存取的部份，可能每秒數百次；而 routing daemon 則是在背景執行的程序，大約半分鐘會更新 routing table 的資訊一次，而更新的資訊可能來自鄰近的 router，或甚至是 ICMP redirect 的封包都可以用來作為更新 routing table 的依據。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;Routing 原則&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;基本上，routing 的規則如下：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;搜尋有無符合的 host&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;搜尋有無符合的 network&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;搜尋 default gateway (預設閘道)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;以上的 routing 工作是由 IP 負責處理；而上面的規則都是去搜尋 routing table 中的資訊，而這些資訊(也稱為 routing policy)都是由 routing daemon 所負責提供。&lt;br /&gt;&lt;br /&gt;routing table 長什麼樣呢? 以下截圖說明：&lt;br /&gt;&lt;div id="gp0k" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 667px; height: 200px;" src="http://docs.google.com/File?id=ddzmw8vs_473c35x6q73_b" /&gt;&lt;/div&gt;&lt;br /&gt;其中兩條被框起來的規則(Flags 的部份有大寫「&lt;b style="color: rgb(255, 0, 0);"&gt;G&lt;/b&gt;」)為 gateway，而 Flags 說明如下：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;U&lt;/b&gt;：表示此規則路徑是正常運作的&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;G&lt;/b&gt;：將封包導向 gateway&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;H&lt;/b&gt;：將封包導向特定的主機&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;D&lt;/b&gt;：表示此規則是由 ICMP Redirect 訊息所新增的&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;M&lt;/b&gt;：表示此規則是由 ICMP Redirect 訊息所修改的&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;關於 routing 時會發生的錯誤種類&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;b&gt;ICMP Host &amp;amp; Network Unreachable Errors&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;當 router 收到 IP datagram 卻無法將其繼續傳送時，就會發生此錯誤，通常此種錯誤出現的原因為網路設定上的錯誤，或是硬體線路沒接好。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;b&gt;ICMP Redirect Errors&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;此錯誤訊息是由 router 所發，目的是用來告知發送 IP datagram 的主機，應該要將封包送到另外一個 router 上。&lt;br /&gt;&lt;br /&gt;以下用圖片來說明一下發生 ICMP Redirect Error 的情境：&lt;br /&gt;&lt;div id="fs0w" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 514px; height: 297px;" src="http://docs.google.com/File?id=ddzmw8vs_47467vdmwfc_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;其中 host 將 IP datagram 送給 R1，因為 R1 是 host 的 default gateway。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;R1 收到封包，檢查 routing table 規則後，發現其實 R2 才是正確的路徑，因此將封包導向 R2。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;除了將封包導向外，R1 也額外發送了 ICMP Redirect Error 的訊息給 host，通知它要修改自己本身的 routing table。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;由這個功能可以瞭解到，若是在複雜一點的 topology 中，要每個 host 都清楚知道封包 routing 的路徑是很難的，但有了這功能後，就可以僅設定 default gateway，接著送封包後就會由 router 通知來改變自身的 routing table 了。&lt;br /&gt;&lt;br /&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;【備註】&lt;br /&gt;&lt;/b&gt;&lt;ol&gt;&lt;li&gt;此種錯誤訊息僅有 router 能發送，host 是不能發送的。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;router 僅能送出 host redirect 而不是 network redirect，理由是因為 router 要掌握 topology 所有的網段資訊不是很容易，而且也有可能覆蓋原本 host 的 routing table 中不需要修改的設定。&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;ICMP Router Discovery Messages&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;此種訊息是用來讓 host 動態取得 routing 資訊用，透過發送此訊息(solicitation)，周遭收到此訊息的 router 便會進行回應(advertisement)；此外，router 還會定期的廣播 router advertisement，讓 host 可以即時更新 routing table 中的資訊。&lt;br /&gt;&lt;br /&gt;從上面的運作方式可以瞭解到：&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;ICMP Router Discovery Message&lt;/b&gt; = &lt;b style="color: rgb(255, 0, 0);"&gt;ICMP Router Solicitation Message&lt;/b&gt; +&lt;br /&gt;                                                    &lt;b style="color: rgb(0, 0, 255);"&gt;ICMP Router Advertisement Message&lt;/b&gt;&lt;br /&gt;&lt;/blockquote&gt;接著是兩種 message 的格式：&lt;br /&gt;&lt;br /&gt;&lt;b style="color: rgb(255, 0, 0);"&gt;ICMP Router Solicitation Message&lt;/b&gt;&lt;br /&gt;&lt;div id="nqfn" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 513px; height: 107px;" src="http://docs.google.com/File?id=ddzmw8vs_475hkv6qpf6_b" /&gt;&lt;/div&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;ICMP Router Advertisement Message&lt;/b&gt;&lt;br /&gt;&lt;div id="k4jd" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 512px; height: 319px;" src="http://docs.google.com/File?id=ddzmw8vs_476grspnwcm_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;Router 在做哪些事情?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在 routing 資訊的傳送中，router 做了哪些事情呢?&lt;br /&gt;&lt;br /&gt;router 會固定每一段時間(約 450~600 秒不等)都發送 advertisement 訊息，若是 router 中有網路介面準備要關閉停用時，會發送一個 lifetime = 0 的 advertisement 訊息通知周圍的 host 與 router 此網路介面將要失效，必須要更新 routing table 中的資訊。&lt;br /&gt;&lt;br /&gt;若是同時有多台 router 在同一個網段中，preference level 的部份就是要由網路管理者來決定了，才有辦法讓 routing policy 有先後順序之分。&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;b&gt;Host 在做哪些事情?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;host 就跟 router 相反了，開機時送出 router solicitation 訊息，以便接收 router 的回應來更新 routing table；當然，也會隨時監聽來自 router 的 advertisement 訊息，以便取得 routing 的最新資訊。&lt;br /&gt;&lt;br /&gt;一般來說，router advertisement 訊息每 10 分鐘就會發送一次，而 lifetime 為 30 分鐘，只要在 30 分鐘之內有收到 router advertisement，就可以一直保持著有 routing 資訊了!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6253731630480360877?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6253731630480360877/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6253731630480360877' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6253731630480360877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6253731630480360877'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/tcpip-illustrated-ip-routing.html' title='[TCP/IP Illustrated] IP Routing'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2780576312111510429</id><published>2009-01-11T21:05:00.002+08:00</published><updated>2011-05-27T11:51:00.374+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] Traceroute</title><content type='html'>&lt;font size="4"&gt;&lt;b&gt;運作原理簡介&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;基本上 traceroute 是使用 ICMP 協定，並透過 IP header 中的 TTL 的值每經過一個 router 會遞減的特性，來取得封包傳遞的路徑。&lt;br&gt;&lt;br&gt;詳細的運作原理說明如下：(以下 client 為執行 traceroute 的主機，server 則為目的地)&lt;br&gt;&lt;ol&gt;&lt;li&gt;client 發送 TTL 為 1 的封包，destination 指定為 server。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;當第一個 router 收到後會將 TTL 減一，此時 TTL 為 0，因此 router 回送 ICMP time exceeded 訊息，如此一來，client 就可以知道封包傳遞路徑中的第一個 router 是哪一個。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;接著發送 TTL 為 2 的封包，同樣的可以接收到來自第二個 router 所回傳的 ICMP time exceeded 訊息。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;一直到封包真正到達 server 時，此時 server 會回應 ICMP port unreachable 訊息，為什麼呢? 原因是因為 client 所發送的封包為 UDP datagram，並指定一個很大的數字(&amp;gt; 30000)，通常不會有 server 會在這麼大的 port number 上提供服務，因此會回傳 ICMP port unreachable 的訊息。&lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;client 收到來自 server 的 ICMP port unreachable 訊息，就完整拼湊出封包傳遞路徑了!&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;tracertroute 實測&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;在 Windows 中的程式名稱為 tracert，在 Linux 則為 tracepath (也有 tracertroute，不過要另外裝套件)，以下是在 Windows 使用的範例圖：&lt;br&gt;&lt;div id="aebu" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 669px; height: 342px;" src="http://docs.google.com/File?id=ddzmw8vs_465d8z2qpg7_b"&gt;&lt;/div&gt;&lt;br&gt;若用 tcpdump 偵測封包往來情況，結果如下：&lt;br&gt;&lt;div id="etfu" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 800px; height: 340px;" src="http://docs.google.com/File?id=ddzmw8vs_466df3kp6g7_b"&gt;&lt;/div&gt;&lt;br&gt;從上面的實測可以得知，在封包傳遞路徑上的節點，都是由 ICMP time exceeded 與 udp port unreachable 來決定的，以下為 ICMP time exceeded 封包的格式：&lt;br&gt;&lt;div id="cv-y" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 507px; height: 187px;" src="http://docs.google.com/File?id=ddzmw8vs_467dws79xdj_b"&gt;&lt;/div&gt;從圖中可以看出，ICMP time exceed 封包的 type 值為 11，而 time exceeded error 又會在兩種情況下發生，分別是在傳送(trasmit，code = 0)以及封包重組(reassembly，code = 1)時。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;IP Source Routing Option&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;這個功能剛好跟 ping 的 record route option 相反，是將 router 的 IP 清單填到封包中，讓封包可以按照清單上的路徑傳遞，有分為 strict/loose source routing，封包格式如下：&lt;br&gt;&lt;div id="rb14" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 514px; height: 90px;" src="http://docs.google.com/File?id=ddzmw8vs_468cjqj338s_b"&gt;&lt;/div&gt;&lt;br&gt;不過這功能似乎不常用，可能高階的網管有可能用到吧......以後學到高階的時候再來研究這個好了。&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Traceroute - 維基百科，自由的百科全書" target="_blank" href="http://zh.wikipedia.org/wiki/Traceroute" id="ccsa"&gt;Traceroute - 維基百科，自由的百科全書&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="網路工具(2) Tracer的功能介紹 [論壇存檔] - PCZONE 討論區" target="_blank" href="http://www.pczone.com.tw/vbb3/archive/t-2109.html" id="iiwc"&gt;網路工具(2) Tracer的功能介紹 [論壇存檔] - PCZONE 討論區&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Frank的五四三: Where is my traceroute" target="_blank" href="http://franks543.blogspot.com/2007/09/where-is-my-traceroute.html" id="jssy"&gt;Frank的五四三: Where is my traceroute&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="令人驚豔的Traceroute GUI網管軟體" target="_blank" href="http://www.training-partners.com.tw/forum/viewtopic.asp?subject_id=62&amp;amp;main_id=6" id="cpdn"&gt;令人驚豔的Traceroute GUI網管軟體&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2780576312111510429?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2780576312111510429/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2780576312111510429' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2780576312111510429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2780576312111510429'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/tcpip-illustrated-traceroute.html' title='[TCP/IP Illustrated] Traceroute'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-8974514644598304523</id><published>2009-01-11T14:48:00.002+08:00</published><updated>2009-01-11T14:49:36.043+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>[Linux Command] T 開頭</title><content type='html'>&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;b&gt;tcpdump&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Tcpdump的使用 | Tsung's Blog" target="_blank" href="http://plog.longwin.com.tw/post/1/374" id="ol68"&gt;Tcpdump的使用 | Tsung's Blog&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-8974514644598304523?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/8974514644598304523/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=8974514644598304523' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8974514644598304523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/8974514644598304523'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/linux-command-t.html' title='[Linux Command] T 開頭'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1300325886409082767</id><published>2009-01-10T20:10:00.002+08:00</published><updated>2011-05-27T11:51:00.375+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TCP-IP'/><title type='text'>[TCP/IP Illustrated] Ping</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;b&gt;簡介&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ping 通常是我們用來驗證主機之間的通訊是否有連通的第一個手段。然而隨著網路技術越趨進步與複雜，光用 ping 已經不足以判斷兩台主機之間是否可以互相進行通訊了，但由於 ping 已經是一個歷史悠久的網路工具程式，因此還是很值得拿來探討一下。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;ping 是如何運作的 ? &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ping 的實作是使用 ICMP echo/reply 來達成的，其中發送 echo 的主機稱為 client，回應 reply 的主機稱為 server，而由於 ping 都已經實作在各 OS 的 kernel 中，因此也不必為了啟用這個功能而安裝特定的軟體或是服務。&lt;br /&gt;&lt;br /&gt;以下是 ICMP echo/reply 的封包格式圖：&lt;br /&gt;&lt;div id="lthn" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 510px; height: 183px;" src="http://docs.google.com/File?id=ddzmw8vs_459ft6575cz_b" /&gt;&lt;/div&gt;封包的欄位說明：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;type&lt;/b&gt;&lt;br /&gt;echo 為 8；reply 為 0。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;code&lt;/b&gt;&lt;br /&gt;echo/reply 皆為 0。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;identifier&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;此欄位儲存 ping client 的 process number，如此一來當收到 reply 後，就可以知道由哪一個 process 來處理。&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b style="color: rgb(0, 0, 255);"&gt;sequence number&lt;/b&gt;&lt;br /&gt;紀錄 ping client 所送出的第幾個封包，從 0 開始依次遞增。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;以下是從 Linux server ping 到 google 的範例：&lt;br /&gt;&lt;div id="r.2-" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 723px; height: 264px;" src="http://docs.google.com/File?id=ddzmw8vs_460ctb6pwgm_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;IP Record Route Option&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;使用 ping 時可以透過「&lt;b&gt;-R&lt;/b&gt;」參數將 record route 選項開啟，如此一來就可以知道封包所經過的路徑與節點，但由於目前大部分主機都關閉對此功能的支援，因此使用這個參數都不會有相關的回應。&lt;br /&gt;&lt;br /&gt;不過雖然 ping 支援紀錄路徑的功能，但還是有最多僅能紀錄 9 組 ip 的限制(即使來回經過的相同節點都要包含)，在目前網路環境下，實用性似乎不足。&lt;br /&gt;&lt;br /&gt;不過以下還是放一下 IP record route 封包存放資料的格式：&lt;br /&gt;&lt;div id="jdny" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 509px; height: 116px;" src="http://docs.google.com/File?id=ddzmw8vs_461fqzggfgk_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;IP Timestamp Option&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;這個就跟 record route option 蠻類似的，只是紀錄的是封包到達每個 hop 的 timstamp 而非 ip address，封包格式如下圖：&lt;br /&gt;&lt;div id="lf2g" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img style="width: 519px; height: 116px;" src="http://docs.google.com/File?id=ddzmw8vs_462ccjf5nfm_b" /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-1300325886409082767?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/1300325886409082767/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=1300325886409082767' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1300325886409082767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/1300325886409082767'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/tcpip-illustrated-ping_10.html' title='[TCP/IP Illustrated] Ping'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-4570125312082903445</id><published>2009-01-09T13:52:00.001+08:00</published><updated>2009-01-09T13:53:06.474+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>[Linux] 透過指令直接設定 IP、Netmask、Gateway</title><content type='html'>今天在 VirtualBox 上安裝 Ubuntu Server，但由於網路環境中沒有 DHCP，因此要進到 /etc/network/interfaces 去修改成 static；但麻煩的是，沒有安裝 vim 套件前，實在是沒辦法編輯(不曉得預設是哪種編輯器....用起來很彆扭)，當然也就沒辦法修改 IP。&lt;br&gt;&lt;br&gt;那........怎麼辦呢? 我要改 IP 跟 Gateway 阿!&lt;br&gt;&lt;br&gt;找了一下資料，發現可以透過指令方式直接指定：(設定範例)&lt;br&gt;&lt;blockquote&gt;root&amp;gt; &lt;b&gt;ifconfig eth0 192.168.1.1 netmask 255.255.255.0&lt;/b&gt;&lt;br&gt;root&amp;gt; &lt;b&gt;route add default gw 192.168.1.254&lt;/b&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;這樣就成功啦!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;font style="color: rgb(0, 0, 255);" size="3"&gt;&lt;b&gt;參考資料&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="Linux 网络接口配置文件及相关工具 (v0.1b)" target="_blank" href="http://www.linuxsir.org/main/?q=node/224" id="m8vo"&gt;Linux 网络接口配置文件及相关工具 (v0.1b)&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="Set gateway IP with ifconfig" target="_blank" href="http://bbs.archlinux.org/viewtopic.php?id=52775" id="wtbu"&gt;Set gateway IP with ifconfig&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-4570125312082903445?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/4570125312082903445/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=4570125312082903445' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4570125312082903445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/4570125312082903445'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2009/01/linux-ipnetmaskgateway.html' title='[Linux] 透過指令直接設定 IP、Netmask、Gateway'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-730607294541492318</id><published>2008-12-25T15:58:00.010+08:00</published><updated>2011-05-27T11:47:54.854+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='Unicode'/><title type='text'>[Oracle] 多國語系的處理</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;前言&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Oracle 對於多國語系的支援是相當強大的，可以隨時根據需求改變使用不同的語系、時間格式、貨幣格式、文字編碼、設數字表示法 … 等等。&lt;/p&gt;  &lt;p&gt;在 Oracle 中是透過一群參數來控制多國語系的設定，這一群參數稱為「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS(Native Language Support) parameter&lt;/span&gt;&lt;/strong&gt;」。&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;檢視並運用 NSL paramter&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;NSL parameter 可以透過 Oracle 所提供的 SQL Developer 工具進行檢視，選擇「&lt;strong&gt;Report&lt;/strong&gt; –&amp;gt; &lt;strong&gt;Data Dictionary Reports&lt;/strong&gt; –&amp;gt; &lt;strong&gt;About Your Database&lt;/strong&gt; –&amp;gt; &lt;strong&gt;National Language Support Parameters&lt;/strong&gt;」，畫面如下：&lt;br /&gt;&lt;img src="http://lh5.ggpht.com/_-MI_81GSZ2I/SVCr4IY47rI/AAAAAAAABdQ/5f3TDpBFQH0/s800/NSL_parameter.PNG" /&gt; &lt;/p&gt;  &lt;p&gt;另外，可以透過以下語法，暫時修改目前連線 session 的語系環境：&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;ALTER SESSION SET &lt;em&gt;parameter-name&lt;/em&gt; = ”&lt;em&gt;value&lt;/em&gt;”;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;以下以範例作說明： &lt;/p&gt;  &lt;blockquote&gt;   &lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--修改語言&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'AMERICAN'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;但需要注意的是，&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;透過 ALTER SESSION 所修改的參數，在重新連線後都會重新變回原本的預設值&lt;/span&gt;&lt;/strong&gt;。&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;建立支援多國語系的環境&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;以下分段說明如何自訂多國語系的環境：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;設定語言(Language)與地區(Territory)參數&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在此部份的參數與影響的部份為：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1、&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_LANGUAGE&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;server 訊息顯示時所用的語言&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;日期與其縮寫的表示方式&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;資料排序時的依據(不同的語系會根據不同的字元標準進行排序) &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;以下為 NLS_LANGUAGE 的使用範例： &lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--修改語言&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'TRADITIONAL CHINESE'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--顯示 : 23-12月-08  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--修改語言&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'AMERICAN'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--顯示 : 23-DEC-08 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2、&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_TERRITORY&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;日期格式&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;十進位字元與分隔符號&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;  &lt;li&gt;本地貨幣符號&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;ISO 貨幣符號 &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;以下為 NLS_TERRITORY 的使用範例：&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--結果如下：&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- NT$24,000.00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- NT$17,000.00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- NT$17,000.00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;salary&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'L99G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; salary&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; employee_id &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;IN&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;101&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;102&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變 territory 為德國&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_TERRITORY&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'GERMANY'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--結果如下：&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- €24.000,00  &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- €17.000,00  &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- €17.000,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;salary&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'L99G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; salary&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; employee_id &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;IN&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;101&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;102&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;設定日期(Date)與時間(Time)參數&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不同的地區都會有自己地區表示時間的格式，但如果不適合用，當然要修改預設值也是沒有問題的，關於日期與時間的 NLS parameter，有以下幾個：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1、&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_DATE_FORMAT&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;除了 NLS_TERRITORY 參數可以改變預設的日期格式外，若要進行客製化的話，就必須透過 NLS_DATE_FORMAT 這個參數了，以下用範例說明： (&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/initparams137.htm#REFRN10119" target="_blank"&gt;官方文件說明&lt;/a&gt;) &lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果 : 24.12.08&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變日期格式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_DATE_FORMAT&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'MM/DD/YYYY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果 : 12/24/2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變日期格式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_DATE_FORMAT&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'"DATE: "MM/DD/YYYY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果 : DATE: 12/24/2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2、&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_DATE_LANGUAGE&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;透過此參數可以改變顯示日期的語言，不過僅會在使用 &lt;a href="http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions180.htm" target="_blank"&gt;TO_CHAR&lt;/a&gt; 與 &lt;a href="http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions183.htm" target="_blank"&gt;TO_DATE&lt;/a&gt; 兩個 function 時有效，以下是範例：(&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/initparams138.htm#REFRN10120" target="_blank"&gt;官方文件說明&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;pre&gt;Created with colorer-take5 library. Type 'sql'&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: ���期三:24 12月 2008 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'Day:Dd Month yyyy'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變表示 DATE 語言&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_DATE_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'FRENCH'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: Mercredi:24 Decembre  2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'Day:Dd Month yyyy'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變表示 DATE 語言&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_DATE_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'AMERICAN'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: Wednesday:24 December  2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'Day:Dd Month yyyy'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3、&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_TIMESTAMP_FORMAT&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &amp;amp; &lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_TIMESTAMP_TZ_FORMAT&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;這兩個其實是一起的，只是一個會改變 select 出來的 timestamp 顯示(NLS_TIMESTAMP_FORMAT)，一個會改變由 TO_CHAR() function 所呈現的 timestamp 顯示(NLS_TIMESTAMP_TZ_FORMAT)。&lt;/p&gt;&lt;p&gt;以下為範例：(&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/initparams148.htm#REFRN10132" target="_blank"&gt;官方文件說明&lt;/a&gt;)&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: 24-12月-08 02.22.38.284000000 下午 ASIA/TAIPEI&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;CURRENT_TIMESTAMP&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--改變 timestamp 顯示格式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; NLS_TIMESTAMP_TZ_FORMAT &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'YYYY-MM-DD HH:MI:SS:FF TZH:TZM'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: 2008-12-24 02:22:38:334000000 +08:00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;CURRENT_TIMESTAMP&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;數字表示法的設定&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;數字的部份，可以透過「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_NUMERIC_CHARACTERS&lt;/span&gt;&lt;/strong&gt;」參數設定千、百萬的分隔字元，以及表示小數點的分隔字元；以下用範例說明：&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: 4,000.00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;4000&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'9G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_NUMERIC_CHARACTERS&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;',.'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果: 4.000,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;4000&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'9G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;貨幣格式的設定&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;貨幣格式的部份可由以下三個參數來設定：&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_CURRENCY&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_ISO_CURRENCY &lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NLS_DUAL_CURRENCY&lt;/span&gt;&lt;/strong&gt; &lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;以下用範例說明使用方式：&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- TWD009.000,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- TWD006.000,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- TWD004.800,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- TWD004.800,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- TWD004.200,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;salary&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'C099G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; salary &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;where&lt;/span&gt; department_id &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;60&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--將貨幣表示更改為法國&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_ISO_CURRENCY&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'FRENCH'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- EUR009.000,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- EUR006.000,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- EUR004.800,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- EUR004.800,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- EUR004.200,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;salary&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'C099G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; salary &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;where&lt;/span&gt; department_id &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 140, 0);"&gt;60&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;排序與搜尋方式的設定&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;不同的語言在資料排序上不盡然相同，有些以字母順序為依據，有些以發音為依據、有些以單字的字母數量為依據；而 Oracle 當然也支援根據不同的情況進行改變。&lt;/p&gt;&lt;p&gt;而影響排序搜尋的 NLS parameter 有兩個，分別是「&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;strong&gt;NLS_SORT&lt;/strong&gt;&lt;/span&gt;」與「&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;strong&gt;NLS_COMP&lt;/strong&gt;&lt;/span&gt;」 以下有兩個參數會影響到系統的運作：&lt;/p&gt;&lt;p&gt;以下用範例來說明： &lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--修改排序方式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_SORT&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'BINARY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cabrio                    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cambrault                 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cambrault                 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Chen                      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Chung                     &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Colmenares&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;LIKE&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'C%'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ORDER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;BY&lt;/span&gt; last_name&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--修改排序方式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_SORT&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'spanish_m'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--執行結果:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cabrio                    &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cambrault                 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Cambrault                 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Colmenares                &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Chen                      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Chung&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;LIKE&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'C%'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ORDER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;BY&lt;/span&gt; last_name&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;此外，若是搜尋時大小寫有別，可以透過類似「&lt;strong&gt;NLS_SORT = ‘BINARY_CI’&lt;/strong&gt;」(Case-Insensitive) 的方式進行設定。&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;設定資料長度的判斷基準&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;由於 Oracle 支援多國語言，其中英文是屬於 single-byte 的字元集，其他許多國家的語言則屬於 multi-byte 的字元集；而在 Oracle 中預設是以 byte 為基準，但實際上有時候還是必須以 char 為基準才是比較正確的。&lt;/p&gt;&lt;p&gt;因此在 Oracle 中可以透過以下語法進行設定： &lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--將計算基準改為 char&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; NLS_LENGTH_SEMANTICS &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'CHAR'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--將計算基準改為 byte&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; NLS_LENGTH_SEMANTICS &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'BYTE'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;設計支援多語系的應用程式&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;官方網站中有&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28298/ch7progrunicode.htm#NLSPG007" target="_blank"&gt;文件說明&lt;/a&gt;，指導開發者如何開發 unicode 的應用程式&lt;/p&gt;&lt;p&gt;要儲存 unicode 的資料到 Oracle 有兩種方式：&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;建立一個 unicode 資料庫。(指定資料庫使用的編碼)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt;指定特定欄位支援 multi-bytes 以儲存 unicode 的資料，在 Oracle 為 &lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NCHAR&lt;/span&gt;&lt;/strong&gt; 資料型態。 (基本上，設定 NCHAR 型態的話，不論資料庫使用的編碼為何，都可以儲存 unicode 的資料) &lt;/li&gt;&lt;/ol&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;strong&gt;使用 Unicode 資料型態&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;在 Oracle 有兩種儲存 unicode 資料的型態，分別為：&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;NCHAR&lt;br /&gt;&lt;br /&gt;&lt;/li&gt; &lt;li&gt;NVARCHAR2 &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;首先說明 NCHAR 使用方式，宣告方式如下：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;CREATE TABLE table1 (column1 NCHAR(30));&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;而 NCHAR 的使用長度上有兩個限制：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;當字元編碼為 UTF-8 時，NCHAR 最多可以儲存 2000 的字元；若是改為 AL16UTF16，就僅能儲存 1000 個字元。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;實際儲存長度最大為 32768 bytes。 &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;根據使用者的宣告，資料長度若不足宣告的欄位長度，則會補足空白字元。&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;另外一種資料型態則為 NVARCHAR2，宣告方式如下：&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;CREATE TABLE tables (column2 NVARCHAR2(2000));&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;而 NVARCHAR2 在使用長度上也是有兩個限制：&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;當字元編碼為 UTF-8 時，NCHAR 最多可以儲存 4000 的字元；若是改為 AL16UTF16，就僅能儲存 2000 個字元。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;實際儲存長度最大為 32768 bytes。 &lt;/li&gt;&lt;/ol&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;使用與處理 Unicode 字串&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在 SQL 處理中，若要指定使用 unicode 字串，有以下幾個方式：&lt;/p&gt;&lt;ol&gt;&lt;li&gt;在單引號旁邊加上大寫「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;N&lt;/span&gt;&lt;/strong&gt;」。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;使用 &lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;NCHR(n)&lt;/span&gt;&lt;/strong&gt; 函式，可以將字元轉為 unicode 編碼，提高程式的可攜帶性。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;使用 &lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;UNISTR(‘&lt;em&gt;string&lt;/em&gt;’)&lt;/span&gt;&lt;/strong&gt; 函式，將字串轉換為 unicode 編碼。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;strong&gt;NCHAR 的轉換&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;在開發多國語系的應用程式時，要考慮的部份除了 server 的編碼外，還包含 client 的編碼，當兩者編碼不同時，資料在傳輸時可能就會因為轉換而造成資料不正確，即使使用 N(‘string’) 的方式也是相同。&lt;/p&gt;&lt;p&gt;此時可以在 DB client 的地方增加一個名稱為「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;ORA_NCHAR_LITERAL_REPLACE&lt;/span&gt;&lt;/strong&gt;」的環境變數，並將值設定為 TRUE，如此一來使用 N(‘string’) 時，系統就會自動轉換為 unicode 來傳輸並儲存囉!&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;在 Function 中使用 NLS parameter&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;在 Oracle 中有些 function 會因為語系、地區的不同而造成使用效果也相對不同(例如：TO_CHAR'、TO_DATE、TO_NUMBER、NLS_UPPER、NLS_LOWER、NLS_INITCAP、NLSSORT … 等等)，因此若是有特殊需求的話，可以直接將 NLS parameter 指定在 function 中，讓操作環境&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;暫時&lt;/span&gt;&lt;/strong&gt;改變。&lt;br /&gt;&lt;p&gt;為了讓 function 開發時可以容易些，有時候必須暫時轉變語系進行處理，否則程式光是要考慮語系的部份可能就太過於複雜了，以下用個範例說明：&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;pre&gt;Created with colorer-take5 library. Type 'sql'&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--這樣搜尋是不被允許的，因為日期格式並非如此表示&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; hire_date &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'01-Jan-1999'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--所以改成美國的表示法&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ALTER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SESSION&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SET&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;NLS_DATE_LANGUAGE&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'American'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--如此一來，不論原本的語系為何，都可以正確顯示搜尋結果囉!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; hire_date &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'01-Jan-1999'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;透過在 function 中指定有個好處，就是不會改變該連線 session 時的 NLS 設定，而只有在該 DML 操作時有效而已，以下用個範例說明： &lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;--直接在 TO_CHAR 函式中設定 NLS parameter&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;WHERE&lt;/span&gt; hire_date &lt;span style="color: rgb(128, 128, 48);"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_DATE&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;'01-Jan-1999'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'DD-MON-YYYY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_DATE_LANGUAGE = American'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;因此若是要避免修改到 NLS 設定而影響其他操作，就將 NLS parameter 放進 function 中。&lt;/p&gt;&lt;p&gt;而有哪些 function 可以接受 NLS parameter ? 而這些 function 可以接受的 NLS parameter 又是哪些呢?&lt;/p&gt;以下為列表：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;TO_DATE&lt;/span&gt;&lt;br /&gt;NLS_DATE_LANGUAGE, NLS_CALENDAR&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;TO_NUMBER&lt;/span&gt;&lt;br /&gt;NLS_NUMERIC_CHARACTERS, NLS_CURRENCY, NLS_ISO_CURRENCY, NLS_DUAL_CURRENCY&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;TO_CHAR&lt;/span&gt;&lt;br /&gt;NLS_DATE_LANGUAGE, NLS_NUMERIC_CHARACTERS, NLS_CURRENCY,NLS_ISO_CURRENCY, NLS_DUAL_CURRENCY, NLS_CALENDAR&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;TO_NCHAR&lt;/span&gt;&lt;br /&gt;NLS_SORT&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;NLS_UPPER&lt;/span&gt;&lt;br /&gt;NLS_SORT&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;NLS_LOWER&lt;/span&gt;&lt;br /&gt;NLS_SORT&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;NLS_INITCAP&lt;/span&gt;&lt;br /&gt;NLS_SORT&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;NLSSORT&lt;/span&gt;&lt;br /&gt;NLS_SORT&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;接著為使用範例：&lt;/p&gt;&lt;blockquote&gt;&lt;pre style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 21/JUIN /1999      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 13/JANV./2000      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 17/SEPT./1987&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;hire_date&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'DD/MON/YYYY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_DATE_LANGUAGE = French'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;"Hire Date"&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 25/12月/2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;SYSDATE&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'DD/MON/YYYY'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_DATE_LANGUAGE='&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;'Traditional Chinese'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;' '&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;"System Date"&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 13.000,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;13000&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'99G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_NUMERIC_CHARACTERS = '&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;',.'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;''&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;"13K"&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; DUAL&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 2.600,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 2.600,00 &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- 4.400,00&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;TO_CHAR&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;salary&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'99G999D99'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_NUMERIC_CHARACTERS='&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;',.'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;' NLS_CURRENCY='&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;'EUR'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;''&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; salary &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;                                                                                  -- ABEL               &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- ANDE               &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- ATKINSON&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;NLS_UPPER&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;last_name&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_SORT = Swiss'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;"Last Name"&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Abel                      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Ande                      &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Atkinson                  &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;-- Austin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;SELECT&lt;/span&gt; last_name &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;FROM&lt;/span&gt; employees &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;ORDER&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(128, 0, 0);"&gt;BY&lt;/span&gt; &lt;span style="font-weight: bold; color: rgb(187, 121, 119);"&gt;NLSSORT&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;last_name&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;'NLS_SORT = German'&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;為了符合多國語系，在開發應用程式時，許多細節就必須注意到，未來才不需要因為語系或是編碼的問題傷透腦筋囉!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-730607294541492318?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/730607294541492318/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=730607294541492318' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/730607294541492318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/730607294541492318'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle.html' title='[Oracle] 多國語系的處理'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_-MI_81GSZ2I/SVCr4IY47rI/AAAAAAAABdQ/5f3TDpBFQH0/s72-c/NSL_parameter.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6278460909145397350</id><published>2008-12-23T14:10:00.003+08:00</published><updated>2011-05-27T11:47:54.855+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[Oracle] Trigger</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;何謂觸發(Trigger) ?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;觸發(Triggers)是當 Table 或是 View 因為 Insert、Delete、Update動作發生時自動觸發的程序(或是因為特定事件的發生，例如：服務啟動)。可以用來描述商業邏輯。跟 stored procedure 很類似，差別在於它不是用來直接呼叫的。&lt;/p&gt;  &lt;p&gt;通常 trigger 被用來作為以下幾項用途：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;資料完整性的檢查      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;稽核與日誌紀錄功能      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;執行複雜的商業邏輯運算與處理      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;衍生欄位資料的計算與產生      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;讓 table 資料有限制的被修改 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;使用語法&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先是 trigger 的使用語法： (詳細語法可參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_7004.htm#SQLRF01405" target="_blank"&gt;官方文件&lt;/a&gt;)     &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;TRIGGER trigger_name    --trigger 名稱&lt;br /&gt;  triggering_statement  --trigger 觸發的條件、依附的 object ... etc&lt;br /&gt;  [trigger_restriction]&lt;br /&gt;BEGIN&lt;br /&gt; triggered_action;  --trigger 所處理的事情&lt;br /&gt;END;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;從語法可以看出，整個 trigger 可以分為四個部份：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;trigger name&lt;/strong&gt;       &lt;br /&gt;在同一個 schema 中，trigger name 必須是唯一的。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;triggering statement        &lt;br /&gt;&lt;/strong&gt;指定讓 trigger 啟動的事件，這些事情可能包含 DML(for table)、DDL(for schema object) 或是資料庫服務啟動、關閉、甚至是發生錯誤時。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;trigger restriction&lt;/strong&gt;       &lt;br /&gt;額外設定的限制，可讓 trigger 在特定情況下(當 restriction = TRUE 時)才啟動。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;triggered action&lt;/strong&gt;       &lt;br /&gt;trigger 所要執行的程式內容。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;觸發(Trigger)的種類&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;在 Oracle 中，trigger 大致可分為五類：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;statement trigger&lt;/strong&gt; (詳細用法可參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABGEAIA" target="_blank"&gt;官方文件&lt;/a&gt;)       &lt;br /&gt;此種 trigger 跟 DML 操作(例如：DELETE、INSERT、UPDATE)有關聯，但每一次的 DML 操作僅會觸發一次 trigger。       &lt;br /&gt;雖然設定在 DML 操作上的 trigger 在 DML 操作發生時僅會出發一次，但可以同時設定多個 trigger 在同一個 DML 操作上，而且還可以透過「FOLLOW」、「PRECEDES」… 等關鍵字來決定多個 trigger 觸發的先後順序。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;row trigger&lt;/strong&gt; (詳細用法可參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABCGBBD" target="_blank"&gt;官方文件&lt;/a&gt;)       &lt;br /&gt;當 table 中的每一列資料發生 INSERT、UPDATE 或是 DELETE 時，此種 trigger 就會觸發。大致跟 statement trigger 運作方式相同，但 row trigger 是針對「&lt;strong&gt;&lt;font color="#ff0000"&gt;每一列&lt;/font&gt;&lt;/strong&gt;」資料進行觸發；因此假設一個 DML 同時影響很多筆資料時，statement trigger 僅會出發一次，但 row trigger 卻會觸發很多次。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;INSTEAD OF&lt;/strong&gt; (詳細用法可參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABECIAE" target="_blank"&gt;官方文件&lt;/a&gt;)       &lt;br /&gt;可以用在當使用者針對 VIEW 或是衍生欄位進行操作時，可透過 trigger 將資料進行正確的資料處理。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;user event trigger&lt;/strong&gt;       &lt;br /&gt;用於 DDL(例如：CREATE、ALTER、DROP、&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABFBEJH" target="_blank"&gt;USER LOGON/LOGOFF&lt;/a&gt; … 等等) 以及特定的 DML 操作(分析、統計、稽核、使用者權限管理)上。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;system event trigger &lt;/strong&gt;      &lt;br /&gt;當資料庫啟動、關閉、或是發生錯誤的事件發生時，會進行觸發。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Trigger 發生的時間點&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;trigger 發生的時間點也必須要注意，因為在 trigger statement 中，有「BEFORE」與「AFTER」兩種可供使用，表示 trigger 觸發的時間點位於「事件發生前」或是「事件發生後」。&lt;/p&gt;  &lt;p&gt;但也不是每個事件都有前後可以設定，例如：STARTUP、SUSPEND、LOGON … 等事件，就僅有 AFTER 可以用；而 SHUTDOWN、LOGOFF … 等事件就僅有 BEFORE 可以用。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Trigger 的設計原則與限制&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;雖然 trigger 看似很好用，可以作很多的管理與控制，但最好還是注意以下幾點原則與限制：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;過度使用 trigger 或許會產生複雜的依賴關係，後續的維護變得很困難。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;確定當某個特定工作執行後，所有相關與相依的工作都有被一一執行。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;避免將 recursive trigger 的發生，否則記憶體裝再多都沒用。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;避免 trigger 的工作會觸發另一個 trigger 而造成連鎖效應，以免造成非預期的情況發生，或是對資料庫效能造成影響。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;不要用 trigger 作一些資料庫已經能做的工作，例如：參考完整性的檢查。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;確定「BEFORE」、「AFTER」的使用有符合規則與需求。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;trigger 的程式碼不宜過多(Oracle 限制不能超過 32 Kb)，若是程式碼太多，或許可以考慮寫成 stored procedure 來處理。      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;確定 trigger 中運作的工作符合資料庫與商業邏輯規則，若是要針對特定人物、特定團體或是特定 application 客製化工作需求，別用 trigger，寫在 application 裡面吧!      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;在 trigger 中無法使用 COMMIT、ROLLBACK、SAVEPOINT … 等關鍵字，因為 DDL 操作已經隱含 COMMIT 在裡面了。      &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;建立 Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff" size="3"&gt;Statement Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;statement trigger 是與 DML 的操作(Insert、Update、Delete)有關，以下用範例說明：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--建立 table 存放 trigger 產生的 log 之用&lt;br /&gt;CREATE TABLE evaluations_log (&lt;br /&gt;    log_date    DATE, &lt;br /&gt;    action      VARCHAR2(50)&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;CREATE OR REPLACE TRIGGER eval_modification_trigger&lt;br /&gt;    --設定當發生 insert、update、delete 以後會觸發&lt;br /&gt;    AFTER INSERT OR UPDATE OR DELETE&lt;br /&gt;    ON evaluations  --指定 table&lt;br /&gt;DECLARE &lt;br /&gt;    log_action evaluations_log.action%TYPE;&lt;br /&gt;BEGIN&lt;br /&gt;    IF INSERTING THEN   --發生 insert&lt;br /&gt;        log_action := 'Insert';&lt;br /&gt;    ELSIF UPDATING THEN --發生 update&lt;br /&gt;        log_action := 'Update';&lt;br /&gt;    ELSIF DELETING THEN --發生 delete&lt;br /&gt;        log_action := 'Delete';&lt;br /&gt;    ELSE &lt;br /&gt;        DBMS_OUTPUT.PUT_LINE('This code is not reachable.');&lt;br /&gt;    END IF;&lt;br /&gt;    &lt;br /&gt;    --執行 log 的動作&lt;br /&gt;    INSERT INTO evaluations_log(log_date, action) VALUES(SYSDATE, log_action);&lt;br /&gt;END &lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff" size="3"&gt;Row Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;與 statement trigger 不同的是，DML 對於每個資料列的操作都會觸發 row trigger 動作，但在 trigger 寫法上，僅有一點點不同而已：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;CREATE OR REPLACE TRIGGER new_evaluation&lt;br /&gt;    --設定發生 insert 前會觸發&lt;br /&gt;    BEFORE INSERT&lt;br /&gt;    ON evaluations  --指定 table&lt;br /&gt;    FOR EACH ROW    --當每筆資料新增時，都會觸發此 trigger&lt;br /&gt;BEGIN&lt;br /&gt;    NULL&lt;br /&gt;END&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff" size="3"&gt;INSTEAD OF Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;instead of trigger 通常用於發生使用者對 view 進行操作時，可以針對使用者傳入的資料進行額外的處理，以下是範例：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;CREATE OR REPLACE TRIGGER update_name_view_trigger&lt;br /&gt;    INSTEAD OF UPDATE   --當發生 update 時，用以下程式碼取代 update 的動作&lt;br /&gt;    ON emp_locations    --指定 view&lt;br /&gt;BEGIN&lt;br /&gt;    --將更新的字串拆開並分別更新 table 中的資料&lt;br /&gt;    UPDATE employees&lt;br /&gt;    SET first_name = substr(:NEW.name, instr(:NEW.name, ',') + 2),&lt;br /&gt;        last_name = substr(:NEW.name, 1, instr(:NEW.name) - 1);&lt;br /&gt;    WHERE employee_id = :OLD.employee;&lt;br /&gt;END &lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#0000ff" size="3"&gt;LOGON &amp;amp; LOGOFF Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;通常此種 trigger 是用於紀錄使用者登入登出 schema object 時紀錄 log 之用，以下為範例：&lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--建立 table 儲存使用者登入登出的紀錄&lt;br /&gt;CREATE TABLE hr_user_log(&lt;br /&gt;    user_name   VARCHAR2(30), &lt;br /&gt;    activity    VARCHAR2(20), &lt;br /&gt;    event_date  DATE&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;--建立 LOGON Trigger&lt;br /&gt;CREATE OR REPLACE TRIGGER note_hr_logon_trigger&lt;br /&gt;    AFTER LOGON     --使用者登入前觸發&lt;br /&gt;    ON HR.SCHEMA    --指定 schema object&lt;br /&gt;BEGIN&lt;br /&gt;    INSERT INTO hr_user_log VALUES(USER, 'LOGON', SYSDATE);&lt;br /&gt;END &lt;br /&gt;&lt;br /&gt;--建立 LOGOFF Trigger&lt;br /&gt;CREATE OR REPLACE TRIGGER note_hr_logoff_trigger&lt;br /&gt;    BEFORE LOGOFF   --使用者登出前觸發&lt;br /&gt;    ON HR.SCHEMA    --指定 schema object&lt;br /&gt;BEGIN&lt;br /&gt;    INSERT INTO hr_user_log VALUES(USER, 'LOGOFF', SYSDATE);&lt;br /&gt;END &lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;停用 &amp;amp; 啟用 Trigger&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;trigger 建立完成後，也可以暫時停用的，之後也還是可以繼續啟用，語法範例如下：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--停用特定的 trigger&lt;br /&gt;ALTER TRIGGER eval_change_trigger DISABLE;&lt;br /&gt;&lt;br /&gt;--啟用特定的 trigger&lt;br /&gt;ALTER TRIGGER eval_change_trigger ENABLE;&lt;br /&gt;&lt;br /&gt;--停用指定 table 相關的所有 trigger&lt;br /&gt;ALTER TABLE evaluations DISABLE ALL TRIGGERS;&lt;br /&gt;&lt;br /&gt; --啟用指定 table 相關的所有 trigger&lt;br /&gt;ALTER TABLE evaluations ENABLE ALL TRIGGERS;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;錯誤排除&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;由於 trigger 建立時會經過 compile 的動作，若是錯誤發生後，想要瞭解錯誤的詳細描述進行排除，或是想要瞭解 trigger 之間有哪些相依的關係，就必須透過 Oracle 中 &lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/toc.htm" target="_blank"&gt;Data Dictionary&lt;/a&gt; 的幫忙! 詳細的 Data Dictionary 資訊可以參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/toc.htm" target="_blank"&gt;官方網站文件&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;以下用範例作說明：   &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--顯示 trigger 編譯時的錯誤&lt;br /&gt;SELECT * FROM USER_ERROR WHERE TYPE = 'TRIGGER';&lt;br /&gt;&lt;br /&gt;--顯示 trigger 之間的相依性&lt;br /&gt;SELECT * FROM ALL_DEPENDENCIES WHERE TYPE = 'TRIGGER';&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;當然範例中僅使用到了 &lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/statviews_5262.htm#BABBADAD" target="_blank"&gt;USER_ERRORS&lt;/a&gt; 與 &lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28320/statviews_1066.htm#i1576452" target="_blank"&gt;ALL_DEPENDENCIES&lt;/a&gt; 兩個 system view，還有很多其他的 system tables &amp;amp; views 可作為它用，就之後再來慢慢探討了!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6278460909145397350?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6278460909145397350/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6278460909145397350' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6278460909145397350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6278460909145397350'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-trigger.html' title='[Oracle] Trigger'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-2778173732398201102</id><published>2008-12-19T16:23:00.002+08:00</published><updated>2011-05-27T11:47:54.857+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] PL/SQL 例外處理</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;前言&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;現在的程式語言中，幾乎都提供了例外處理的功能，當然 PL/SQL 也不能例外，除了提供例外處理的功能外，還可以讓使用者自訂例外喔!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;Oracle 內建的例外種類&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;其實在 Oracle 當中就已經內建了許多例外的定義了，例如：&lt;strong&gt;NO_DATA_FOUND&lt;/strong&gt;(當 SELECT INTO 的語法沒有回傳任何資料列時會觸發)、&lt;strong&gt;CASE_NOT_FOUND&lt;/strong&gt;(當條件中沒有任何一項符合且沒有 ELSE 選項時會觸發)，詳細的內建例外說明，可以參&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/errors.htm#BABHDGGG" target="_blank"&gt;考官方網站的文件&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;而例外的使用方式如下：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;EXCEPTION&lt;br /&gt;    WHEN exception_name_1 THEN  --捕捉第一個例外&lt;br /&gt;        --例外處理&lt;br /&gt;        ...;&lt;br /&gt;        DBMS_OUTPUT.PUT_LINE(message_1);&lt;br /&gt;        ...&lt;br /&gt;    WHEN OTHERS THEN    --捕捉沒定義的例外&lt;br /&gt;        --例外處理&lt;br /&gt;        ...&lt;br /&gt;        DBMS_OUTPUT.PUT_LINE(message_others);&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;以下用個範例說明如何使用 Oracle 的內建範例：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;PROCEDURE eval_department(department_id IN employees.department_id%TYPE) AS&lt;br /&gt;    --宣告 cursor variable (型態為 package specification 中定義的 emp_refcursor_type)&lt;br /&gt;    emp_cursor  emp_refcursor_type;&lt;br /&gt;    &lt;br /&gt;    --目前正在處理的部門ID&lt;br /&gt;    department_curr departments.department_id%TYPE; &lt;br /&gt;BEGIN&lt;br /&gt;    department_curr := department_id;&lt;br /&gt;    FOR loop_c IN 1..3 LOOP&lt;br /&gt;        --開啟 cursor&lt;br /&gt;        OPEN emp_cursor FOR&lt;br /&gt;            SELECT *&lt;br /&gt;            FROM employees e&lt;br /&gt;            WHERE e.department_id = department_curr;&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        eval_loop_control(emp_cursor);&lt;br /&gt;        &lt;br /&gt;        DBMS_OUTPUT.PUT_LINE('Determining necessary evaluations in department #' || department_curr);&lt;br /&gt;        &lt;br /&gt;        --關閉 cursor&lt;br /&gt;        CLOSE emp_cursor;&lt;br /&gt;        &lt;br /&gt;        department_curr := department_curr + 10;&lt;br /&gt;    END LOOP;&lt;br /&gt;    &lt;br /&gt;    --定義錯誤處理的實作&lt;br /&gt;    EXCEPTION&lt;br /&gt;        WHEN NO_DATA_FOUND THEN&lt;br /&gt;            DBMS_OUTPUT.PUT_LINE('The query did noy return a result set');&lt;br /&gt;        WHEN OTHERS THEN&lt;br /&gt;            DBMS_OUTPUT.PUT_LINE('Other exception occurs');&lt;br /&gt;END eval_department;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;自訂例外&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;自訂的例外在宣告上很有彈性，可以放在 subprogram 中，也可以放在 package specification 或是 package body 中，完全隨使用者方便。&lt;/p&gt;  &lt;p&gt;而自訂例外的語法如下：    &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--自訂例外&lt;br /&gt;exception_name EXCEPTION;&lt;br /&gt;&lt;br /&gt;--設定例外發生條件以觸發例外&lt;br /&gt;IF condition THEN&lt;br /&gt;    RAISE exception_name;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;  &lt;p&gt;接著是自訂例外觸發條件與例外處理的範例：   &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--FUNCTION 的實作內容&lt;br /&gt;FUNCTION calculate_score(evaluation_id  IN scores.evaluation_id%TYPE, &lt;br /&gt;                       performance_id IN scores.performance_id%TYPE) RETURN NUMBER AS&lt;br /&gt;    --自訂例外&lt;br /&gt;    weight_wrong    EXCEPTION;&lt;br /&gt;    score_wrong     EXCEPTION;&lt;br /&gt;    &lt;br /&gt;    n_score     scores.score%TYPE;                --VARIABLE&lt;br /&gt;    n_weight    performance_parts.weight%TYPE;    --VARIABLE&lt;br /&gt;    running_total NUMBER := 0;  --計算中使用&lt;br /&gt;    max_score   CONSTANT scores.score%TYPE := 9;  --CONSTANT&lt;br /&gt;    max_weight  CONSTANT performance_parts.weight%TYPE := 1; --CONSTANT&lt;br /&gt;BEGIN&lt;br /&gt;    --實作於此處&lt;br /&gt;    SELECT s.SCORE INTO n_score --設定 n_score 的值  &lt;br /&gt;    FROM SCORES s&lt;br /&gt;    WHERE evaluation_id = s.evaluation_id;&lt;br /&gt;&lt;br /&gt;    SELECT p.weight INTO n_weight --設定 n_weight 的值&lt;br /&gt;    FROM performance_parts p&lt;br /&gt;    WHERE performance_id = p.performance_id;&lt;br /&gt;&lt;br /&gt;    --設定觸發例外的條件 ===== (start)&lt;br /&gt;    BEGIN&lt;br /&gt;        IF n_weight &gt; max_weight OR n_weight &lt; 0 THEN&lt;br /&gt;            RAISE weight_wrong;&lt;br /&gt;        END IF;&lt;br /&gt;    END;&lt;br /&gt;    BEGIN&lt;br /&gt;        IF n_score &gt; max_score OR n_score &lt; 0 THEN&lt;br /&gt;            RAISE score_wrong;&lt;br /&gt;        END IF;&lt;br /&gt;    END;&lt;br /&gt;    --設定觸發例外的條件 ===== (end)&lt;br /&gt;    &lt;br /&gt;    --計算 running_total&lt;br /&gt;    running_total := max_score * max_weight;&lt;br /&gt;&lt;br /&gt;    --回傳值&lt;br /&gt;    RETURN running_total;&lt;br /&gt;    &lt;br /&gt;    --自訂例外處理&lt;br /&gt;    EXCEPTION&lt;br /&gt;        WHEN weight_wrong THEN&lt;br /&gt;            DBMS_OUTPUT.PUT_LINE('重量必須介於 0 與 ' || max_weight || ' 之間');&lt;br /&gt;            RETURN -1;&lt;br /&gt;        WHEN score_wrong THEN&lt;br /&gt;            DBMS_OUTPUT.PUT_LINE('分數必須介於 0 與 ' || max_score || ' 之間');&lt;br /&gt;            RETURN -1;&lt;br /&gt;END CALCULATE_SCORE;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-2778173732398201102?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/2778173732398201102/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=2778173732398201102' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2778173732398201102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/2778173732398201102'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-plsql.html' title='[Oracle] PL/SQL 例外處理'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-7696862988276034426</id><published>2008-12-19T15:13:00.002+08:00</published><updated>2011-05-27T11:47:54.858+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] 相同型態的資料集合 - Collection</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;何謂 Collection ?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;之前有提到 &lt;a href="http://godleon.blogspot.com/2008/12/oracle-record.html" target="_blank"&gt;record 型態&lt;/a&gt;，可以讓使用者自訂不同的型別集合；而 collection 則是相同資料型態的集合，簡單來說可以將它視為 Array。&lt;/p&gt;  &lt;p&gt;collection 是用來存放一群相同型態的資料用，由於可以直接透過索引(index)或是鍵值(key)直接存取，因此速度很快；而在 Oracle 中提供三種不同的 collection：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;index-by table        &lt;br /&gt;&lt;/strong&gt;高彈性且高效能的 collection 型態，也是最常用的。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;nested table&lt;/strong&gt;       &lt;br /&gt;適合用來處理龐大資料的 collection 型態。       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;VARRAY&lt;/strong&gt;       &lt;br /&gt;適合用來處理少數資料的 collection 型態。 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;這裡介紹較為常用的 index-by table，其存在的型態可以是 Array(用索引值取得值)，或是 key-value 的集合(用 key 取得值)。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;為何 Collection 效能優越?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;要了解 collection 為什麼要能優越，就必須先知道 collection 是如何運作的，使用 collection 的方式大致如下：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;定義 cursor，用來取得資料庫的資料用      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;定義 index-by table，並指定所包含的資料型態為 cursor 所取得的資料(通常為 &lt;strong&gt;%ROWTYPE&lt;/strong&gt;)       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;定義 collection 變數，型態為步驟二所定義的 index-by table      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;開啟 cursor，並一次將所有資料取出並存入步驟三所定義的 collection 變數後，關閉 cursor      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;後續處理與應用 collection 變數中所包含的所有資料 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;從上面可以知道 collection 是與 cursor 搭配使用的，將資料從資料庫取出後便暫存於記憶體中，因此處理起來的效能才會優越。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;使用範例&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;以下用範例說明：   &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;CREATE OR REPLACE PROCEDURE collectionTest AS&lt;br /&gt;    --定義 cursor(取得員工與工作資訊)&lt;br /&gt;    CURSOR employees_jobs_cursor IS&lt;br /&gt;                SELECT e.first_name, e.last_name, e.job_id&lt;br /&gt;                FROM emlpoyees e&lt;br /&gt;                ORDER BY e.job_id, e.last_name, e.first_name&lt;br /&gt;    &lt;br /&gt;    --定義 cursor(取得工作資訊)&lt;br /&gt;    CURSOR jobs_cursor IS&lt;br /&gt;                SELECT j.job_id, j.job_title&lt;br /&gt;                FROM jobs j;&lt;br /&gt;&lt;br /&gt;    --定義 collection 資料結構 (employees_jobs_type)&lt;br /&gt;    TYPE employees_jobs_type IS TABLE OF employees_jobs_cursor%ROWTYPE INDEX BY PLS_INTEGER;&lt;br /&gt;    --定義儲存 collection 資料的 table 變數&lt;br /&gt;    employees_jobs employees_job_type;&lt;br /&gt;    &lt;br /&gt;    --定義 collection 資料結構 (jobs_type)&lt;br /&gt;    TYPE jobs_type IS TABLE OF jobs_cursor%ROWTYPE INDEX BY PLS_INTEGER;&lt;br /&gt;    --定義儲存 collection 資料的 table 變數&lt;br /&gt;    jobs jobs_type;&lt;br /&gt;    &lt;br /&gt;    --定義 collection 資料結構 (job_titles_type)&lt;br /&gt;    TYPE job_titles_type IS TABLE OF jobs.job_title%TYPE INDEX BY jobs_job_id%TYPE;&lt;br /&gt;    --定義儲存 collection 資料的 table 變數&lt;br /&gt;    job_titles job_titles_type;&lt;br /&gt;BEGIN&lt;br /&gt;    --透過 cursor 取得資料，並置於 collection 變數中 ====== (start)&lt;br /&gt;    --開啟 cursor 並從資料庫取得資料&lt;br /&gt;    OPEN employees_jobs_cursor;&lt;br /&gt;    &lt;br /&gt;    --將取得的資料塞入 collection 變數中&lt;br /&gt;    FETCH employees_job_cursor BULK COLLECT INTO employees_jobs;&lt;br /&gt;    &lt;br /&gt;    --關閉 cursor&lt;br /&gt;    CLOSE employees_jobs_cursor;&lt;br /&gt;    &lt;br /&gt;    OPEN jobs_cursor;&lt;br /&gt;    FETCH job_cursor BULK COLLECT INTO jobs;&lt;br /&gt;    CLOSE jobs_cursor;&lt;br /&gt;    --透過 cursor 取得資料，並置於 collection 變數中 ====== (end)&lt;br /&gt;    &lt;br /&gt;    --將 cursor 取得的 job 資訊塞入 job_titles collection 中&lt;br /&gt;    FOR i IN 1..jobs.COUNT() LOOP&lt;br /&gt;        job_titles(jobs(i).job_id) := jobs(i).job_title;&lt;br /&gt;    END LOOP;&lt;br /&gt;    &lt;br /&gt;    --列出員工資訊&lt;br /&gt;    FOR i IN 1..employees_jobs.COUNT() LOOP&lt;br /&gt;        DBMS_OUTPUT.PUT_LINE(RPAD(employees_jobs(i).employee_id, 10) || RPAD(employees_jobs(i).first_name, 15) || RPAD(employees_jobs(i).last_name, 15) || job_titles(employees(i).job_id));&lt;br /&gt;    END LOOP;&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    --使用 collection 中的 FIRST() 與 NEXT()&lt;br /&gt;    DECLARE i jobs.job_id%TYPE := job_titles.FIRST();&lt;br /&gt;    WHILE i IS NOT NULL LOOP&lt;br /&gt;        DBMS_OUTPUT.PUT_LINE(RPAD(job_titles(i).job_id, 10) || job_titles(i).job_title);&lt;br /&gt;        i := job_titles.NEXT(i);&lt;br /&gt;    END LOOP;&lt;br /&gt;END collectionTest;&lt;br /&gt;&lt;/textarea&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-7696862988276034426?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/7696862988276034426/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=7696862988276034426' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7696862988276034426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/7696862988276034426'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-collection.html' title='[Oracle] 相同型態的資料集合 - Collection'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3660442461840660979</id><published>2008-12-18T17:42:00.006+08:00</published><updated>2011-05-27T11:47:54.859+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] Cursor 與 Cursor Variable 的使用</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;何謂 Cursor ?&lt;/span&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;cursor 為 PL/SQL 中內建的一種 pointer，可用來擷取整個資料集合，並讓使用者可以逐筆資料的進行存取。&lt;/p&gt;  &lt;p&gt;在 Oracle 中，cursor 分為兩種，分別是：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;implicit(內隱) cursor      &lt;br /&gt;&lt;/strong&gt;在 Oracle 所提供的功能中，可以發現許多 implicit cursor 的蹤跡，例如：PL/SQL 中的 FOR…LOOP。     &lt;br /&gt;而這一類的 cursor 是沒有辦法透過程式去控制的，而是由 Oracle 本身來進行控制與管理。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;explicit(外顯) cursor&lt;/strong&gt;     &lt;br /&gt;此種 cursor 就可以透過開發 PL/SQL 的方式來進行控制與管理，讓管理者可以有很大的彈性來使用。 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;預設中，Oracle 提供了上限 50 個 cursor 可供使用，但若因為開發需求而導致同時需要更多的 cursor 時，可以透過調整起始參數「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;OPEN_CURSOR&lt;/span&gt;&lt;/strong&gt;」來達成。&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;使用 Explicit Cursor&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;每個 explicit cursor 都會有以下幾個屬性作為程式控制之用：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;%NOTFOUND&lt;/strong&gt;     &lt;br /&gt;根據從資料集合中擷取的最後一筆資料，來決定回傳 TRUE(有資料) or FALSE(沒資料)。     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;%FOUND&lt;/strong&gt;     &lt;br /&gt;與 %NOTFOUND 相反。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;%ROWCOUNT&lt;/strong&gt;     &lt;br /&gt;回傳資料集合中所包含的資料筆數。當 cursor 從資料集合擷取過資料後，就可以使用此屬性。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;%ISOPEN      &lt;br /&gt;&lt;/strong&gt;若是 cursor 狀態為 open，則回傳 TRUE；反之則回傳 FALSE。 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;為了暫時存放從 cursor 擷取出來的資料列，必須定義一個暫存的變數，而這個變數的型態通常為一列資料(row data)。&lt;/p&gt;  &lt;p&gt;以下介紹 cursor 使用的語法： (更詳細的語法可以參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/explicit_cursor.htm#LNPLS01313" target="_blank"&gt;官方網站文件&lt;/a&gt;)   &lt;br /&gt;&lt;/p&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;DECLARE&lt;br /&gt;--宣告 cursor，並指定擷取資料集合的 SQL 語法(query_definition)&lt;br /&gt;CURSOR cursor_name type IS query_definition;&lt;br /&gt;&lt;br /&gt;--開啟 cursor(此時會根據宣告時中定義的 SQL 語法取得資料集合)&lt;br /&gt;OPEN cursor_name&lt;br /&gt;   LOOP&lt;br /&gt;   --取得 cursor 目前所在的資料列(必須使用暫存變數來儲存取得的資料列)&lt;br /&gt;   FETCH record INTO buffer_var;&lt;br /&gt;&lt;br /&gt;   --當 cursor 已經將資料集合的資料巡覽完畢&lt;br /&gt;   EXIT WHEN cursor_name%NOTFOUND;&lt;br /&gt;&lt;br /&gt;   --各式各樣的處理工作&lt;br /&gt;   ...;&lt;br /&gt;   END LOOP;&lt;br /&gt;--關閉 cursor(之後 cursor 就不能再繼續使用)&lt;br /&gt;CLOSE cursor_name;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;接著介紹使用範例：  &lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--PROCEDURE 的實作內容&lt;br /&gt;PROCEDURE eval_department(department_id IN employees.department_id%TYPE) AS&lt;br /&gt;    --宣告暫存變數，儲存 cursor data&lt;br /&gt;    emp_record  employees%ROWTYPE;&lt;br /&gt;    &lt;br /&gt;    --宣告變數，檢查所有員工是否需要重新評估績效&lt;br /&gt;    all_evals BOOLEAN;&lt;br /&gt;    &lt;br /&gt;    --今日日期&lt;br /&gt;    today DATE;&lt;br /&gt;    &lt;br /&gt;    --宣告 cursor&lt;br /&gt;    CURSOR emp_cursor IS &lt;br /&gt;        SELECT * &lt;br /&gt;        FROM employees e &lt;br /&gt;        WHERE department_id = e.department_id;        &lt;br /&gt;BEGIN&lt;br /&gt;    --根據月份判斷是否重新計算績效&lt;br /&gt;    today := SYSDATE;&lt;br /&gt;    IF(EXTRACT(MONTH FROM today) &lt; 6) THEN&lt;br /&gt;        --僅針對新進員工計算績效&lt;br /&gt;        all_evals := FALSE;&lt;br /&gt;    ELSE&lt;br /&gt;        --全部重新計算&lt;br /&gt;        all_evals := TRUE;&lt;br /&gt;    END IF;&lt;br /&gt;    &lt;br /&gt;    --開啟 cursor&lt;br /&gt;    OPEN emp_cursor;&lt;br /&gt;    &lt;br /&gt;    DBMS_OUTPUT.PUT_LINE('Determining evaluations necessary in department #' || department_id);&lt;br /&gt;    &lt;br /&gt;    LOOP&lt;br /&gt;        --透過 cursor 取得一筆資料並存入暫存變數&lt;br /&gt;        FETCH emp_cursor INTO emp_record;&lt;br /&gt;        &lt;br /&gt;        --若 cursor 已將資料取完，則跳出迴圈&lt;br /&gt;        EXIT WHEN emp_cursor%NOTFOUND;&lt;br /&gt;        &lt;br /&gt;        IF all_evals THEN&lt;br /&gt;            --呼叫之前宣告的 procedure&lt;br /&gt;            add_eval(emp_record.employee_id, today);&lt;br /&gt;        ELSIF(eval_frequency(emp_record.employee_id) = 2) THEN&lt;br /&gt;            --呼叫之前宣告的 procedure&lt;br /&gt;            add_eval(emp_record.employee_id, today);&lt;br /&gt;        END IF;&lt;br /&gt;    END LOOP;&lt;br /&gt;    &lt;br /&gt;    DBMS_OUTPUT.PUT_LINE('Processed ' || emp_cursor%ROWCOUNT || ' records.');&lt;br /&gt;    &lt;br /&gt;    --關閉 cursor&lt;br /&gt;    CLOSE emp_cursor;&lt;br /&gt;END eval_department;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;使用 Cursor Variable：REF Cursor&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;從上面 cursor 的使用方式可以知道，由於 cursor 的使用必須寫在 subprogram 中，並無法在程式中動態的變更所擷取的資料，因此在使用上是靜態的。&lt;/p&gt;  &lt;p&gt;然而，若要在程式中動態的改變 cursor 所擷取的資料，或是將 cursor 所取到的資料集合當作參數傳到另一個 subprogram 中，就必須改用 REF Cursor 了!&lt;/p&gt;  &lt;p&gt;什麼是 cursor variable 呢? 簡單來說，就是「&lt;strong&gt;&lt;span style="color:#ff0000;"&gt;儲存指向實際 cursor 的指標的變數&lt;/span&gt;&lt;/strong&gt;」，以下用一張簡單的圖來說明：&lt;/p&gt;  &lt;p&gt;&lt;img src="http://lh6.ggpht.com/_-MI_81GSZ2I/SUoT4ZOW3YI/AAAAAAAABbc/jsj-zDf67UY/s800/CursorVariable.jpeg" /&gt; &lt;/p&gt;  &lt;p&gt;其中假設實際 cursor 所在的記憶體位址為 0XBC34AD，而 cursor variable 儲存的就是 0XBC34AD 這個記憶體位址，而非 cursor 本身。&lt;/p&gt;  &lt;p&gt;也由於 cursor variable 有如此特性，因此假設同時有多個 cursor 同時開啟，就可以將不同的記憶體位址指定給 cursor variable，這樣就可以讓 cursor variable 很快速的取得不同 cursor 從資料庫所擷取到的不同資料。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color:#ff0000;"&gt;【附註】&lt;/span&gt;&lt;/strong&gt;cursor 將資料從資料庫取出後，就存放於記憶體中，接著後續的處理就會很快速。&lt;/p&gt;  &lt;p&gt;瞭解 cursor variable 與 ref cursor 的關係後，就先來說明使用的語法：   &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;DECLARE&lt;br /&gt;--定義 ref cursor 與回傳值的資料型態(return_type)，稱為 strongly typed&lt;br /&gt;--也可不定義回傳的資料型態，稱為 weakly typed&lt;br /&gt;TYPE cursor_type IS REF CURSOR RETURN return_type;&lt;br /&gt;&lt;br /&gt;--定義 cursor variable(為 cursor pointer，指向實際的 cursor)&lt;br /&gt;cursor_variable cursor_type;&lt;br /&gt;&lt;br /&gt;--定義變數儲存 cursor 回傳的資料&lt;br /&gt;single_record return_type;&lt;br /&gt;&lt;br /&gt;--使用 cursor variable 開啟 cursor，並依照 query_definition 從資料庫取得資料 &lt;br /&gt;OPEN cursor_variable FOR query_definition;&lt;br /&gt;LOOP&lt;br /&gt;    --取得一筆資料，暫存入 single_record 中&lt;br /&gt;    FETCH record INTO single_record;&lt;br /&gt;    &lt;br /&gt;    --資料集合已經巡覽完畢，離開迴圈&lt;br /&gt;    EXIT WHEN cursor_name%NOTFOUND;&lt;br /&gt;    &lt;br /&gt;    --任何其他實作置於此處&lt;br /&gt;    ...;&lt;br /&gt;END LOOP;&lt;br /&gt;&lt;br /&gt;--關閉 cursor&lt;br /&gt;--注意! 不是 cursor_variable 喔!&lt;br /&gt;CLOSE cursor_name;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;有一點需要注意到的是，在定義 ref cursor 時不一定需要同時定義回傳值(return_type)。&lt;/p&gt;  &lt;p&gt;若是有定義回傳值，則 cursor 取回來的資料為 &lt;strong&gt;strongly typed&lt;/strong&gt;；反之若是沒有定義回傳值，cursor 取回的資料則為 &lt;strong&gt;weakly typed&lt;/strong&gt;。&lt;/p&gt;  &lt;p&gt;若是 strongly typed，若是在程式撰寫中發生與定義型別不符的錯誤，就可以在編譯(compile)時期發現；而若是 weakly typed，由於沒有定義回傳型別，因此在使用時可以給定任何型別，若是使用上小心點，似乎也提供了蠻大的彈性。&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;REF CURSOR 使用範例&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;首先先將 ref cursor 與其他 subprogram 的定義放到 package specification 中： &lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;CREATE OR REPLACE PACKAGE EMP_EVAL AS&lt;br /&gt;    -- 宣告 PROCEDURE 與 FUNCTION&lt;br /&gt;    PROCEDURE eval_department(department_id IN employees.department_id%type);&lt;br /&gt;&lt;br /&gt;    --計算所有人的績效&lt;br /&gt;    PROCEDURE eval_everyone;&lt;br /&gt;&lt;br /&gt;    --定義 ref cursor&lt;br /&gt;    TYPE emp_refcursor_type IS REF CURSOR RETURN employees%ROWTYPE;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;接著是其他 subprogram 的實作部份： &lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--PROCEDURE 的實作內容&lt;br /&gt;PROCEDURE eval_department(department_id IN employees.department_id%TYPE) AS&lt;br /&gt;--宣告 cursor variable (型態為 package specification 中定義的 emp_refcursor_type)&lt;br /&gt;emp_cursor  emp_refcursor_type;&lt;br /&gt;&lt;br /&gt;--目前正在處理的部門ID&lt;br /&gt;department_curr departments.department_id%TYPE; &lt;br /&gt;BEGIN&lt;br /&gt;    department_curr := department_id;&lt;br /&gt;    FOR loop_c IN 1..3 &lt;br /&gt;    LOOP&lt;br /&gt;        --開啟 cursor&lt;br /&gt;        OPEN emp_cursor FOR&lt;br /&gt;            SELECT *&lt;br /&gt;            FROM employees e&lt;br /&gt;            WHERE e.department_id = department_curr;&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;        eval_loop_control(emp_cursor);&lt;br /&gt;        &lt;br /&gt;        DBMS_OUTPUT.PUT_LINE('Determining necessary evaluations in department #' || department_curr);&lt;br /&gt;        &lt;br /&gt;        --關閉 cursor&lt;br /&gt;        CLOSE emp_cursor;&lt;br /&gt;        &lt;br /&gt;        department_curr := department_curr + 10;&lt;br /&gt;    END LOOP;&lt;br /&gt;END eval_department;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PROCEDURE add_eval(emp_record IN employees%ROWTYPE, today IN DATE) AS&lt;br /&gt;BEGIN&lt;br /&gt;    --新增資料&lt;br /&gt;    INSERT INTO evaluations VALUES( evaluations_seq.NEXTVAL, &lt;br /&gt;                                    emp_record.employee_id, &lt;br /&gt;                                    today, &lt;br /&gt;                                    emp_record.job_id,&lt;br /&gt;                                    emp_record.manager_id, &lt;br /&gt;                                    emp_record.department_id,&lt;br /&gt;                                    0);&lt;br /&gt;END add_eval;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PROCEDURE eval_loop_control(emp_cursor IN emp_refcursor_type) AS&lt;br /&gt;    --定義暫存變數，儲存透過 cursor 擷取的資料&lt;br /&gt;    emp_record  employees%ROWTYPE;&lt;br /&gt;&lt;br /&gt;    --宣告變數，檢查所有員工是否需要重新評估績效&lt;br /&gt;    all_evals   BOOLEAN;&lt;br /&gt;    &lt;br /&gt;    --今日日期&lt;br /&gt;    today   DATE;&lt;br /&gt;BEGIN&lt;br /&gt;    --取得今天的日期&lt;br /&gt;    today := SYSDATE;&lt;br /&gt;    IF(EXTRACT(MONTH FROM today) &lt; 6) THEN&lt;br /&gt;        all_evals := FALSE;&lt;br /&gt;    ELSE&lt;br /&gt;        all_evals := TRUE;&lt;br /&gt;    END IF;&lt;br /&gt;    &lt;br /&gt;    LOOP&lt;br /&gt;        --透過 cursor 擷取一筆資料&lt;br /&gt;        FETCH emp_cursor INTO emp_record;&lt;br /&gt;        &lt;br /&gt;        --當 cursor 已經將資料擷取完畢，跳離迴圈&lt;br /&gt;        EXIT WHEN emp_cursor%NOTFOUND;&lt;br /&gt;        &lt;br /&gt;        IF all_evals THEN&lt;br /&gt;            add_eval(emp_record, today);&lt;br /&gt;        ELSIF(eval_frequency(emp_record.employee_id) = 2) THEN  --呼叫其他 subprogram，先忽略這邊&lt;br /&gt;            add_eval(emp_record, today);&lt;br /&gt;        END IF;&lt;br /&gt;    END LOOP;&lt;br /&gt;END　eval_loop_control;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PROCEDURE eval_everyone AS&lt;br /&gt;    --宣告 cursor variable (型態為 package specification 中定義的 emp_refcursor_type)&lt;br /&gt;    emp_cursor emp_refcursor_type;&lt;br /&gt;BEGIN&lt;br /&gt;    --開啟 cursor，取得資料集合&lt;br /&gt;    OPEN emp_cursor FOR SELECT * FROM employees;&lt;br /&gt;    &lt;br /&gt;    DBMS_OUTPUT.PUT_LINE('Determining the number of necessary evaluations');&lt;br /&gt;    &lt;br /&gt;    --呼叫 subprogram，傳入 cursor variable&lt;br /&gt;    eval_loop_control(emp_cursor);&lt;br /&gt;    &lt;br /&gt;    DBMS_OUTPUT.PUT_LINE('Processed ' || emp_cursor%ROWCOUNT || ' records.');&lt;br /&gt;    &lt;br /&gt;    --關閉 cursor (上面呼叫的 subprogram 並未把 cursor 關閉)&lt;br /&gt;    CLOSE emp_cursor;&lt;br /&gt;END eval_everyone;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3660442461840660979?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3660442461840660979/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3660442461840660979' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3660442461840660979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3660442461840660979'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-cursor-cursor-variable.html' title='[Oracle] Cursor 與 Cursor Variable 的使用'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_-MI_81GSZ2I/SUoT4ZOW3YI/AAAAAAAABbc/jsj-zDf67UY/s72-c/CursorVariable.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-6609246073110711020</id><published>2008-12-18T11:26:00.001+08:00</published><updated>2008-12-18T13:35:28.593+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><title type='text'>[Oracle] compile package 時總會出現的警告</title><content type='html'>&lt;p&gt;每次編輯 package 完後，要 compile 時總是會出現以下的警告訊息：&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Warning(1): PLW-06015: 參數 PLSQL_DEBUG 已不使用; 請改用 PLSQL_OPTIMIZE_LEVEL = 1&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;img src="http://lh3.ggpht.com/_-MI_81GSZ2I/SUnBsdiIM9I/AAAAAAAABbU/M0vwgsikygU/s800/oracle_warning_compile_package.PNG" /&gt; &lt;/p&gt;  &lt;p&gt;訊息中告訴我們 PLSQL_DEBUG 已經不使用了，但 Oracle 好像預設還是會開啟的樣子，因此使用下列語法把 PLSQL_DEBUG 功能關閉，並將 PLSQL_OPTIMIZE_LEVEL 設定為 1：&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;ALTER SESSION SET PLSQL_DEBUG = false;      &lt;br /&gt;ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 1;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;如此一來這惱人的警告訊息就不會再出現囉!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="3"&gt;參考資料&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://tw.myblog.yahoo.com/jw!37UBDJOGGRCT69pAGBXOw7JoSw--/article?mid=179" target="_blank"&gt;認識系統參數 - Tiger's Blog - Yahoo!奇摩部落格&lt;/a&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.pcdiy.com.tw/runpc/download/200404/123P221.txt" target="_blank"&gt;Oracle 10g系列專欄（5）- Oracle 10g的PL/SQL增強功能&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-6609246073110711020?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/6609246073110711020/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=6609246073110711020' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6609246073110711020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/6609246073110711020'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-compile-package.html' title='[Oracle] compile package 時總會出現的警告'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_-MI_81GSZ2I/SUnBsdiIM9I/AAAAAAAABbU/M0vwgsikygU/s72-c/oracle_warning_compile_package.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-3966124135874345146</id><published>2008-12-18T09:47:00.009+08:00</published><updated>2011-05-27T11:47:54.860+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] 複雜資料結構 - RECORD</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;何謂 RECORD ?&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;RECORD 是由一群各自儲存於不同欄位的相關資料所組合而成的群組，每個資料都有各自的名稱與資料型態。&lt;/p&gt;  &lt;p&gt;使用 RECOED 的好處在於當 RECORD 被當作參數丟入 subprogram 處理的時候，或是同時包含多個不同 table 中的不同欄位時，處理的效率是很好的。&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;建立 RECORD 資料型態&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; 首先，先了解建立 RECORD 型態的語法：  &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;--定義 RECORD&lt;br /&gt;TYPE record_name IS RECORD(&lt;br /&gt;    --定義 RECORD 中的欄位與型態&lt;br /&gt;    field_1 data_type,&lt;br /&gt;    ...&lt;br /&gt;    field_n data_type);&lt;br /&gt;...&lt;br /&gt;--宣告變數值代替自訂的 RECORD 型態&lt;br /&gt;variable_name record_name;&lt;br /&gt;...&lt;br /&gt;BEGIN&lt;br /&gt;    ...&lt;br /&gt;    --必須使用「.」來取得 RECORD 中的欄位值&lt;br /&gt;    ...variable_name.field1...;&lt;br /&gt;    ...variable_name.fieldn...;&lt;br /&gt;    ...&lt;br /&gt;END...;&lt;br /&gt;&lt;/textarea&gt;  &lt;br /&gt;&lt;br /&gt; 接著是實際定義 RECORD 的範例：(定義於 package specification 中)  &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;--定義薪資資訊 RECORD             &lt;br /&gt;type sal_info is record (&lt;br /&gt;    job_id    jobs.job_id%type, &lt;br /&gt;    sal_min   jobs.min_salary%type, &lt;br /&gt;    sal_max   jobs.max_salary%type, &lt;br /&gt;    salary    employees.salary%type, &lt;br /&gt;    sal_raise number(3, 3)&lt;br /&gt;);&lt;/textarea&gt;  &lt;br /&gt;&lt;br/&gt; &lt;p&gt;&lt;strong&gt;&lt;font size="4"&gt;RECORD 的使用&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; 當 RECORD 定義好後就可以使用了，以下為使用範例：  &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;procedure salary_schedule(emp in sal_info) as&lt;br /&gt;accumulation_sal number;&lt;br /&gt;begin&lt;br /&gt;    --使用自訂的 RECORD - sal_info&lt;br /&gt;    dbms_output.put_line('If the salary of ' || emp.salary || ' increased by ' || round((emp.sal_raise * 100), 0) || '% each year, it would be ');&lt;br /&gt;    accumulation_sal := emp.salary;&lt;br /&gt;    while accumulation_sal &lt;= emp.sal_max loop&lt;br /&gt;        accumulation_sal := accumulation_sal * (1 + emp.sal_raise);&lt;br /&gt;        dbms_output.put(round(accumulation_sal, 2) || ', ');&lt;br /&gt;    end loop;&lt;br /&gt;    dbms_output.put_line('in successive years.');&lt;br /&gt;end salary_schedule;&lt;br /&gt;&lt;/textarea&gt;  &lt;br /&gt;&lt;br /&gt; 以下擷取之前範例(EMP_EVAL)的部份程式碼作為範例：  &lt;br /&gt;&lt;textarea class="sql" name="code"&gt;&lt;br /&gt;create or replace&lt;br /&gt;PACKAGE BODY EMP_EVAL AS&lt;br /&gt;    --local subprogram 定義&lt;br /&gt;    --像 C 語言一樣，將 procedure 或 function 先定義好，之後的時作就不需要考慮呼叫先後順序的問題&lt;br /&gt;    function eval_frequency(employee_id in employees.employee_id%type) RETURN pls_integer;&lt;br /&gt;    procedure salary_schedule(emp in sal_info);&lt;br /&gt;  &lt;br /&gt;    --僅供內部使用的 function&lt;br /&gt;    function eval_frequency(employee_id in employees.employee_id%type)&lt;br /&gt;        return pls_integer as&lt;br /&gt;    hire_date   employees.hire_date%type;&lt;br /&gt;    today       employees.hire_date%type;&lt;br /&gt;    eval_freq   pls_integer;&lt;br /&gt;    emp_sal     sal_info;   --自訂的 RECORD 型態&lt;br /&gt;    begin&lt;br /&gt;        --設定今天日期&lt;br /&gt;        select sysdate into today from dual;    &lt;br /&gt;&lt;br /&gt;        --取得員工開始工作日期&lt;br /&gt;        select e.hire_date into hire_date from employees e where e.employee_id = employee_id;&lt;br /&gt;&lt;br /&gt;        --判斷年資是否大於十年&lt;br /&gt;        if((hire_date + (interval '120' month)) &lt; today) then&lt;br /&gt;            eval_freq := 1;&lt;br /&gt;&lt;br /&gt;            --取得給 emp_sal(sal_info) 的資料 ========== (start)&lt;br /&gt;            select e.job_id into emp_sal.job_id from employees e where e.employee_id = employee_id;&lt;br /&gt;            select j.min_salary into emp_sal.sal_min from jobs j where j.job_id = emp_sal.job_id;&lt;br /&gt;            select j.max_salary into emp_sal.sal_max from jobs j where j.job_id = emp_sal.job_id;&lt;br /&gt;            select e.salary into emp_sal.salary from employees e where e.employee_id = employee_id;&lt;br /&gt;            emp_sal.sal_raise := 0;&lt;br /&gt;            --取得給 emp_sal(sal_info) 的資料 ========== (end)&lt;br /&gt;&lt;br /&gt;            --根據 job_id 決定每年調薪幅度&lt;br /&gt;            case emp_sal.job_id&lt;br /&gt;                when 'PU_CLERK' then emp_sal.sal_raise := 0.08;&lt;br /&gt;                when 'SH_CLERK' then emp_sal.sal_raise := 0.07;&lt;br /&gt;                when 'ST_CLERK' then emp_sal.sal_raise := 0.06;&lt;br /&gt;                when 'HR_REP' then emp_sal.sal_raise := 0.05;&lt;br /&gt;                when 'PR_REP' then emp_sal.sal_raise := 0.05;&lt;br /&gt;                when 'MK_REP' then emp_sal.sal_raise := 0.04;&lt;br /&gt;                else null;&lt;br /&gt;            end case;&lt;br /&gt;&lt;br /&gt;            --列出每年薪資成長幅度&lt;br /&gt;            if(emp_sal.sal_raise != 0) then &lt;br /&gt;                salary_schedule(emp_sal); &lt;br /&gt;            end if;&lt;br /&gt;        else  --年資尚未超過十年&lt;br /&gt;            eval_freq := 2;&lt;br /&gt;        end if;&lt;br /&gt;&lt;br /&gt;        --回傳值&lt;br /&gt;        return eval_freq;&lt;br /&gt;  end eval_frequency;&lt;br /&gt;&lt;br /&gt;    procedure salary_schedule(emp in sal_info) as&lt;br /&gt;    accumulation_sal number;&lt;br /&gt;    begin&lt;br /&gt;        --使用自訂的 RECORD - sal_info&lt;br /&gt;        dbms_output.put_line('If the salary of ' || emp.salary || ' increased by ' || round((emp.sal_raise * 100), 0) || '% each year, it would be ');&lt;br /&gt;        accumulation_sal := emp.salary;&lt;br /&gt;        while accumulation_sal &lt;= emp.sal_max loop&lt;br /&gt;            accumulation_sal := accumulation_sal * (1 + emp.sal_raise);&lt;br /&gt;            dbms_output.put(round(accumulation_sal, 2) || ', ');&lt;br /&gt;        end loop;&lt;br /&gt;        dbms_output.put_line('in successive years.');&lt;br /&gt;    end salary_schedule;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/textarea&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4428257381149033865-3966124135874345146?l=godleon.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://godleon.blogspot.com/feeds/3966124135874345146/comments/default' title='張貼意見'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4428257381149033865&amp;postID=3966124135874345146' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3966124135874345146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4428257381149033865/posts/default/3966124135874345146'/><link rel='alternate' type='text/html' href='http://godleon.blogspot.com/2008/12/oracle-record.html' title='[Oracle] 複雜資料結構 - RECORD'/><author><name>曾建銘</name><uri>http://www.blogger.com/profile/00909689459926867079</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4428257381149033865.post-1269020382369898197</id><published>2008-12-17T16:44:00.020+08:00</published><updated>2011-05-27T11:47:54.861+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='PL-SQL'/><title type='text'>[Oracle] 開發 &amp; 使用 Stored Procedures</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;概觀&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;PL/SQL 是在資料庫端執行的，因此若是將資料庫處理的程式都寫成 stored procedure，撰寫程式時就不需要對資料庫進行頻繁的連線與資料往來，如此一來效能也會相對有所提昇。&lt;/p&gt;  &lt;p&gt;在 PL/SQL 中，程式設計的基本單元為獨立的 &lt;strong&gt;stored procedure&lt;/strong&gt;、&lt;strong&gt;function&lt;/strong&gt; 或是 &lt;strong&gt;package：&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;stored procedure&lt;/strong&gt;：沒有回傳值。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;function&lt;/strong&gt;：有回傳值。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;package&lt;/strong&gt;：&lt;span style="color: rgb(0, 0, 0);"&gt;類似 Java 中的 package 或是 .NET 中的 namespace 一樣&lt;/span&gt;，可以用來區隔相同名稱的 stored procedure 或是 function。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Procedures &amp;amp; Functions&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;procedure 與 function 是由三個主要部份所組成，分別是：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;宣告部份(declarative-part)&lt;/strong&gt;     &lt;br /&gt;此部份所使用的關鍵字為「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;DECLARE&lt;/span&gt;&lt;/strong&gt;」，用來定義變數與常數之用。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;執行部份(executable-part)&lt;/strong&gt;     &lt;br /&gt;此部份是程式執行的部份，會使用關鍵字「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;BEGIN&lt;/span&gt;&lt;/strong&gt;」與「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;END&lt;/span&gt;&lt;/strong&gt;」包住來表示開始與結束。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;例外處理部份(exception-handling part)&lt;/strong&gt;     &lt;br /&gt;透過關鍵字「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;EXCEPTION&lt;/span&gt;&lt;/strong&gt;」來處理程式中可能會發生的錯誤情況。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;建立 Stored Procedures &amp;amp; Functions&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;建立 stored procedure 的語法如下：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;CREATE OR REPLACE procedure_name(arg1 data_type, ...)&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;   ....&lt;br /&gt;END procedure_name;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt; 以下來個建立 procedure 的範例：(&lt;a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_6009.htm#SQLRF01309" target="_blank"&gt;官方網站使用說明&lt;/a&gt;)&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;CREATE OR REPLACE PROCEDURE ADD_EVALUATION&lt;br /&gt;(&lt;br /&gt;   EVALUATION_ID   IN    NUMBER,&lt;br /&gt;   EMPLOYEE_ID     IN    NUMBER,&lt;br /&gt;   EVALUATION_DATE IN    DATE,&lt;br /&gt;   JOB_ID          IN    VARCHAR2,&lt;br /&gt;   MANAGER_ID      IN    NUMBER,&lt;br /&gt;   DEPARTMENT_ID   IN    NUMBER&lt;br /&gt;)&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;   NULL;&lt;br /&gt;END ADD_EVALUATION;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt; 再來個建立 function 的範例：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;CREATE OR REPLACE FUNCTION CALCULATE_SCORE&lt;br /&gt;(&lt;br /&gt;   CAT     IN  VARCHAR2,&lt;br /&gt;   SCORE   IN  NUMBER,&lt;br /&gt;   WEIGHT  IN  NUMBER&lt;br /&gt;)&lt;br /&gt;   RETURN NUMBER&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt;   RETURN NULL;&lt;br /&gt;END CALCULATE_SCORE;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;刪除 Stored Procedures &amp;amp; Functions&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt; 語法更簡單了：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;DROP PROCEDURE ADD_EVALUATION;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;Packages&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;procedure 與 function 根據其所在之處，有三種不同的有效範圍：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;standalone procedure(function)&lt;/strong&gt;：不包含於任何的 package 或是 subprogram 中，屬於 schema-level。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;packaged subprogram&lt;/strong&gt;：定義於 package 中，由 package 進行區隔。     &lt;br /&gt;  &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;local subprogram&lt;/strong&gt;：定義於 subprogram 或是 PL/SQL 程式碼區段中，這一類的程式無法從外界被呼叫，類似 Inner(Nested) Class。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;將 procedure 或是 function 定義於 package 之下有什麼好處呢? 若是 standalone 的 procedure(function)，所能接收的參數型態僅能是向量型態(NUMBER、VARCHAR2、DATE)的變數，若是比較複雜的結構像是 RECORD 就沒辦法了；但若是定義在 package 中就可以囉!&lt;/p&gt;  &lt;p&gt;而 package 包含了兩個部份，分別是定義(specification)的部份與實作(body)的部份；而整個作法很類似 C 語言中針對 function 的定義與處理，也就是「&lt;strong&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;在 specification 中定義公用的 procedure(or function) 以及相關參數，並在 body 中實作定義&lt;/span&gt;&lt;/strong&gt;」。&lt;/p&gt;  &lt;p&gt;關於 package 的詳細使用方式，可以參考&lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/packages.htm#LNPLS009" target="_blank"&gt;官方網站&lt;/a&gt;的文章。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;建立 Package&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt; 範例(specification)：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--定義 PACKAGE&lt;br /&gt;CREATE OR REPLACE PACKAGE EMP_EVAL&lt;br /&gt;AS&lt;br /&gt;   -- 宣告 PROCEDURE 與 FUNCTION&lt;br /&gt;   PROCEDURE EVAL_DEPARTMENT(DEPARTMENT_ID IN NUMBER);&lt;br /&gt;   FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN NUMBER, PERFORMANCE_ID IN NUMBER) RETURN NUMBER;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt; 範例(body)：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--設定 PACKAGE 的實作內容&lt;br /&gt;CREATE OR REPLACE PACKAGE BODY EMP_EVAL&lt;br /&gt;AS&lt;br /&gt;   --PROCEDURE 的實作內容&lt;br /&gt;   PROCEDURE EVAL_DEPARTMENT(DEPARTMENT_ID IN NUMBER)&lt;br /&gt;   AS&lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       NULL;&lt;br /&gt;   END EVAL_DEPARTMENT;&lt;br /&gt;  &lt;br /&gt;   --FUNCTION 的實作內容&lt;br /&gt;   FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN NUMBER, PERFORMANCE_ID IN NUMBER) RETURN NUMBER&lt;br /&gt;   AS&lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       RETURN NULL;&lt;br /&gt;   END CALCULATE_SCORE;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;刪除 Package&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;DROP PACKAGE EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 0);font-size:130%;" &gt;變數(variable)與常數(constant)的定義&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;撰寫 procedure 與 function 的優點是在 PL/SQL 中，可以使用由 Oracle 提供，但不能用於 table 欄位定義的資料型態，像是 BOOLEAN、RECORD、REF … 等等。&lt;/p&gt;  以下用個簡單範例說明 variable 與 constant 的使用方式：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--設定 PACKAGE 的實作內容&lt;br /&gt;CREATE OR REPLACE PACKAGE BODY EMP_EVAL&lt;br /&gt;AS&lt;br /&gt;   --PROCEDURE 的實作內容&lt;br /&gt;   PROCEDURE EVAL_DEPARTMENT(DEPARTMENT_ID IN NUMBER)&lt;br /&gt;   AS&lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       NULL;&lt;br /&gt;   END EVAL_DEPARTMENT;&lt;br /&gt;  &lt;br /&gt;   --FUNCTION 的實作內容&lt;br /&gt;   FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN NUMBER, PERFORMANCE_ID IN NUMBER) RETURN NUMBER&lt;br /&gt;   AS&lt;br /&gt;       --變數(variable)與常數(constant)宣告於此處&lt;br /&gt;       n_score   NUMBER(1, 0);&lt;br /&gt;      &lt;br /&gt;       --VARIABLE&lt;br /&gt;       n_weight  NUMBER;      &lt;br /&gt;      &lt;br /&gt;       --VARIABLE&lt;br /&gt;       max_score   CONSTANT NUMBER(1, 0) := 9;&lt;br /&gt;      &lt;br /&gt;       --CONSTANT&lt;br /&gt;       max_weight  CONSTANT NUMBER(8, 8) := 1;&lt;br /&gt;      &lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       RETURN NULL;&lt;br /&gt;   END CALCULATE_SCORE;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;將變數(or 常數)與資料表欄位型態連結&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;若是要將 variable 或是 constant 與 table 中欄位的型態設定為相同，為了避免欄位型態的改變而造成程式發生錯誤，可透過「&lt;strong&gt;%TYPE&lt;/strong&gt;」關鍵字來處理，以下舉個例子：&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;--設定 PACKAGE 的實作內容&lt;br /&gt;CREATE OR REPLACE PACKAGE BODY EMP_EVAL&lt;br /&gt;AS&lt;br /&gt;   --PROCEDURE 的實作內容&lt;br /&gt;   PROCEDURE EVAL_DEPARTMENT(DEPARTMENT_ID IN NUMBER)&lt;br /&gt;   AS&lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       NULL;&lt;br /&gt;   END EVAL_DEPARTMENT;&lt;br /&gt;  &lt;br /&gt;   --FUNCTION 的實作內容&lt;br /&gt;   --將 EVALUATION_ID 的型態與 SCORES 中的 EVALUATION_ID 欄位型態連結&lt;br /&gt;   --將 PERFORMANCE_ID 的型態與 SCORES 中的 PERFORMANCE_ID 欄位型態連結&lt;br /&gt;   FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN SCORES.EVALUATION_ID%TYPE, PERFORMANCE_ID IN SCORES.PERFORMANCE_ID%TYPE) RETURN NUMBER&lt;br /&gt;   AS&lt;br /&gt;       --變數(variable)與常數(constant)宣告於此處&lt;br /&gt;       --將 n_score 的型態與 SCORES 中的 SCORE 欄位型態連結&lt;br /&gt;       --將 n_weight 的型態與 PERFORMANCE_PARTS 中的 WEIGHT 欄位型態連結&lt;br /&gt;       --常數的部分也是連結到 TABLE 的欄位型態&lt;br /&gt;       n_score   SCORES.SCORE%TYPE;             &lt;br /&gt;      &lt;br /&gt;       --VARIABLE&lt;br /&gt;       n_weight  PERFORMANCE_PARTS.WEIGHT%TYPE; &lt;br /&gt;      &lt;br /&gt;       --VARIABLE&lt;br /&gt;       max_score   CONSTANT SCORES.SCORE%TYPE := 9;            &lt;br /&gt;      &lt;br /&gt;       --CONSTANT&lt;br /&gt;       max_weight  CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE := 1;&lt;br /&gt;   BEGIN&lt;br /&gt;       --實作於此處&lt;br /&gt;       RETURN NULL;&lt;br /&gt;   END CALCULATE_SCORE;&lt;br /&gt;END EMP_EVAL;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;如此一來，若是 SCORE 中的 EVALUATION_ID、PERFORMANCE_ID 的型態改變，程式中定義的 variable 或是 constant 的型態也會跟著改變囉。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="color: rgb(0, 0, 255);font-size:100%;" &gt;設定變數值&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;設定變數值有很多方式，以下舉例：&lt;/p&gt; &lt;strong&gt;直接指定或是經由計算：&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN SCORES.EVALUATION_ID%TYPE, PERFORMANCE_ID IN SCORES.PERFORMANCE_ID%TYPE) RETURN NUMBER&lt;br /&gt;AS&lt;br /&gt;   n_score     SCORES.SCORE%TYPE;               &lt;br /&gt;  &lt;br /&gt;   --VARIABLE&lt;br /&gt;   n_weight    PERFORMANCE_PARTS.WEIGHT%TYPE;   &lt;br /&gt;   --VARIABLE&lt;br /&gt;   running_total NUMBER := 0; &lt;br /&gt;  &lt;br /&gt;   --計算中使用&lt;br /&gt;   max_score   CONSTANT SCORES.SCORE%TYPE := 9; &lt;br /&gt;  &lt;br /&gt;   --CONSTANT&lt;br /&gt;   max_weight  CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE := 1;&lt;br /&gt;BEGIN&lt;br /&gt;   --實作於此處&lt;br /&gt;   running_total := max_score * max_weight;&lt;br /&gt;   RETURN running_total;&lt;br /&gt;END CALCULATE_SCORE;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;從資料庫中取值：&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;FUNCTION CALCULATE_SCORE(EVALUATION_ID  IN SCORES.EVALUATION_ID%TYPE, PERFORMANCE_ID IN SCORES.PERFORMANCE_ID%TYPE) RETURN NUMBER&lt;br /&gt;AS&lt;br /&gt;   n_score     SCORES.SCORE%TYPE;               &lt;br /&gt;  &lt;br /&gt;   --VARIABLE&lt;br /&gt;   n_weight    PERFORMANCE_PARTS.WEIGHT%TYPE;   &lt;br /&gt;  &lt;br /&gt;   --VARIABLE&lt;br /&gt;   running_total NUMBER := 0; &lt;br /&gt;  &lt;br /&gt;   --計算中使用&lt;br /&gt;   max_score   CONSTANT SCORES.SCORE%TYPE := 9; &lt;br /&gt;  &lt;br /&gt;   --CONSTANT&lt;br /&gt;   max_weight  CONSTANT PERFORMANCE_PARTS.WEIGHT%TYPE := 1;&lt;br /&gt;      &lt;br /&gt;BEGIN&lt;br /&gt;   --實作於此處&lt;br /&gt;   SELECT s.SCORE INTO n_score&lt;br /&gt;   --設定 n_score 的值&lt;br /&gt;   FROM SCORES s&lt;br /&gt;   WHERE EVALUATION_ID = s.EVALUATION_ID;&lt;br /&gt;  &lt;br /&gt;   SELECT p.weight INTO n_weight&lt;br /&gt;   --設定 n_weight 的值&lt;br /&gt;   FROM PERFORMANCE_PARTS p&lt;br /&gt;   WHERE PERFORMANCE_ID = p.PERFORMANCE_ID;&lt;br /&gt;  &lt;br /&gt;   --計算 running_total&lt;br /&gt;   running_total := max_score * max_weight;&lt;br /&gt;  &lt;br /&gt;   --回傳值&lt;br /&gt;   RETURN running_total;&lt;br /&gt;END CALCULATE_SCORE;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;strong&gt;從資料庫取值，並將新增一筆資料至另外一個 table&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;procedure add_eval(employee_id in employees.employee_id%type, today in date)&lt;br /&gt;as&lt;br /&gt;   job_id        employees.job_id%type;&lt;br /&gt;   manager_id    employees.manager_id%type;&lt;br /&gt;   department_id employees.department_id%type;&lt;br /&gt;begin&lt;br /&gt;   --從 employees 表格中取得值&lt;br /&gt;   select e.job_id into job_id&lt;br /&gt;   from employees e&lt;br /&gt;   where employee_id = e.employee_id;&lt;br /&gt;  &lt;br /&gt;   select e.manager_id into manager_id&lt;br /&gt;   from employees e&lt;br /&gt;   where employee_id = e.employee_id;&lt;br /&gt;  &lt;br /&gt;   select e.department_id into department_id&lt;br /&gt;   from employees e&lt;br /&gt;   where employee_id = e.employee_id;&lt;br /&gt;  &lt;br /&gt;   --新增資料&lt;br /&gt;   insert into evaluations values(evaluations_seq.NEXTVAL, employee_id, today, job_id, manager_id, department_id, 0);&lt;br /&gt;end add_eval;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;span style="font-size:130%;"&gt;流程控制&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt; &lt;strong&gt;IF 與 CASE 的搭配範例：&lt;/strong&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;function eval_frequency(employee_id in employees.employee_id%type) return pls_integer&lt;br /&gt;as&lt;br /&gt;   hire_date   employees.hire_date%type;&lt;br /&gt;   today       employees.hire_date%type;&lt;br /&gt;   eval_freq   pls_integer;&lt;br /&gt;   job_id      employees.job_id%type;&lt;br /&gt;begin&lt;br /&gt;   --設定今天日期&lt;br /&gt;   select sysdate into today from dual;&lt;br /&gt;  &lt;br /&gt;   --取得員工開始工作日期&lt;br /&gt;   select e.hire_date into hire_date from employees e 
