2009年9月29日 星期二
在 ASP.Net 程式裡避免 User 連續觸發 Button
2009年9月27日 星期日
項目'LocalSqlServer'已加入
< add name="LocalSqlServer" connectionString="Data Source=192.168.1.1,5433;Initial Catalog=Test;User ID=sa;Password=sa" providerName="System.Data.SqlClient"/>
自己也只有這個地方在設定資料庫連線而已,真不知道為何還是會出現已加入的錯誤訊息,但把程式安裝在其他台電腦卻又是正常的。所幸,在MSDN上發現一篇類似問題的解法,就是在 < add name="LocalSqlServer" /> 之前,先強制移除,也就是使用 < remove
name="LocalSqlServer"/> 。這招真的有效,下次如果有人也遇到相同的狀況,可以試試。
BinarySearch (二)
首先,我定義了一個簡單的 Person 類別:
class Person
{
public string Name = string.Empty;
public string Department = string.Empty;
public Person (string strName, string strDep)
{
Name=strName;
Department=strDep;
}
public string ShowDetail()
{
return string.Format("Name:{0}, Dep:{1}", Name, Department);
}
}
接著,我很開心的一一鍵入我的測試資料:
Person p1 = new Person("paladin", "BPO");
Person p2 = new Person("hugo", "BPO");
Person p3 = new Person("ken", "BPO");
Person p4 = new Person("keen", "BPO");
Person p5 = new Person("polly", "BPO");
Person p6 = new Person("panda", "BPO");
Person p7 = new Person("lillian", "BPO");
Person p8 = new Person("gemma", "BPO");
Person p9 = new Person("hana", "BPO");
Person[] arrayOffice = { p1, p2, p3, p4, p5, p6, p7, p8, p9 };
Array.Sort(arrayOffice);
當我寫到這裡時,傻住了,目前我的 arrayOffice 陣列,可以排序ㄇ?當程式一執行,馬上就丟出了不好的消息:「無法比較陣列中的兩個元素」。的確,字串、數字是可以用來比較大小,但是自己所定義的類別,如果你沒定下比較規則,那真的是拿芭樂比蓮霧了。
所以,重新修改了自己所定義的 Person 類別,讓他實作 IComparable 介面 來解決。
class Person :IComparable //宣告使用了 IComparable 介面
{
// 原先的程式碼
// XXXXXXXXXXXXX
// XXXXXXXXXXXXX
//實做 IComparable 介面
int IComparable.CompareTo(object obj)
{
Person p2 = obj as Person;
if (p2 == null) throw new ArgumentException("Object is not a Person!");
int iNameResult = this.Name.CompareTo(p2.Name);
if (iNameResult == 0)
{
int iDepResult = this.Department.CompareTo(p2.Department);
return iDepResult;
}
else
{
return iNameResult;
}
}
在自己所實作的 CompareTo( )裡,先比較兩個 Person 的 Name 是否一致,如果一致,接著再比較Department 是否一致。也就是當 Name 與 Department 相同時,才視這兩個 Person 物件為相等。
當解決了 Sort( ) 的問題後,接下來的 BinarySearch( )就不是問題了,於是可以繼續將先前打住的程式繼續往下寫下去。
Person p1 = new Person("paladin", "BPO");
Person p2 = new Person("hugo", "BPO");
Person p3 = new Person("ken", "BPO");
Person p4 = new Person("keen", "BPO");
Person p5 = new Person("polly", "BPO");
Person p6 = new Person("panda", "BPO");
Person p7 = new Person("lillian", "BPO");
Person p8 = new Person("gemma", "BPO");
Person p9 = new Person("hana", "BPO");
Person[] arrayOffice = { p1, p2, p3, p4, p5, p6, p7, p8, p9 };
Array.Sort(arrayOffice);
foreach (Person p in arrayOffice)
Console.WriteLine(p.ShowDetail());
Person pSearch = new Person("panda", "BPO");
int iIndex = Array.BinarySearch(arrayOffice,pSearch);
Console.WriteLine("Index of 'panda' object is :" + iIndex.ToString());
Console.Read();
BinarySearch (一)
string strInput = "paladin,hugo,ken,keen,polly,panda,lillian,gemma,hana";
string[] strArray = strInput.Split(',');
foreach (string s in strArray)
{
Console.WriteLine(s);
}
int iLocation=Array.BinarySearch(strArray, "panda");
Console.WriteLine("Index of 'panda' is :"+iLocation.ToString());
Console.Read();
蠻不給面子的,竟然沒用!
後來發現,要使用 BinarySearch( ),必須要先將資料進行排序才行,也就是說,不排序,就不給用。而在 Array 物件,他也同時提供了 Sort( )方法,正是使用 BinarySearch( ) 所需要的。於是修改了一下上面的程式,加上 Array.Sort(strArray) 。
string strInput = "paladin,hugo,ken,keen,polly,panda,lillian,gemma,hana";
string[] strArray = strInput.Split(',');
Array.Sort(strArray);
foreach (string s in strArray)
{
Console.WriteLine(s);
}
int iLocation=Array.BinarySearch(strArray, "panda");
Console.WriteLine("Index of 'panda' is :"+iLocation.ToString());
Console.Read();
的確,加上排序後,查詢的功能就正確了。但這時心裡頭不免偷偷地「暗」一下微軟,幹麼不乾脆一點,還要讓人這麼麻煩。後來發現,其實這是有原因的。Binary Search (二分搜尋法),是用來搜尋已經排序過的資料。基本上,是先將要比較的資料與所有資料的中間值作比較,根據比較結果的大、小或相等,再來決定下一個搜尋範圍或直接得到搜尋結果。而這種搜尋方式,當然會比我們寫一個迴圈從第一筆慢慢找到最後一筆還來的快許多。
然而,別忘了使用 BinarySearch ( ) 的前提是必須先將資料排序,所以必須將排序所花的時間與搜尋時間加在一起才公平。在效能上來說,如果你要查詢的陣列只有使用一次而已,循序搜尋也不見得會比較慢,因為當資料量很龐大時,光排序也需要花不少時間。相反地,如果你的陣列會一直不斷的被重複使用,只要事先執行一次排序,之後就只需不斷地呼叫 BinarySearch( )則會較佔優勢,這正也是為何自己先前質疑使用 BinarySearch( ) 為何要與 Sort( ) 分開的原因。
2009年9月26日 星期六
Tomcat 6 & JDK 6
JAVA 所選擇的是 Java SE Development Kit 的 JDK 6 Update 16 版本。
C:\Program Files\Java\jdk1.6.0_16
當安裝完 JAVA 與 Tomcat 後,需要作一些環境設定。
打開 [我的電腦] - [右鍵] - [內容] - [進階] - [環境變數] - 在環境變數下選擇 [新增]
變數名稱 | 變數值 |
CLASSPATH | C:\Program Files\Java\jdk1.6.0_16\bin |
CATALINA_HOME | C:\Tomcat |
JAVA_HOME | C:\Program Files\Java\jdk1.6.0_16 |
如此,就完成了 Windows XP 安裝 JSP 開發環境的安裝了。
資料夾 | 說明 |
bin | 程式指令(啟動與停止) |
common | 執行所需jar函式庫 |
conf | 設定檔 |
logs | 日誌檔 |
webapps | 存放網頁應用程式目錄 |
但在 6.X 版,已經廢棄了 common 資料夾了。而原先在 /common/lib ,現在則是
將 /lib 資料夾提到根目錄下。所以在根目錄下面,就可以找到 lib 資料夾了。原先用來
存放擴展的 jar 檔案,也因此改放到根目錄下的 /lib 資料夾下(也就是說,當你有需要
引用別人包好的 jar 函式類別時,記得要放到 /lib 下方)。
參考網址一:http://tw.myblog.yahoo.com/aloha-tw/article?mid=359
參考網址二:http://www.javayou.com/diary/6413
2009年9月21日 星期一
An INSERT EXEC statement cannot be ne...
An INSERT EXEC statement cannot be nested 的錯誤訊息。
SQL 語法如下:
結果是正常的,但跟 insert into #tFinishAll (IsFinish) 一起執行時,
就會出錯。
發現它裡面也有類似先建立一個暫存資料表,然後又透過 執行
Store Procedure 來新增資料的方式。
詳細文章可參考:http://www.windows-tech.info/15/fe648af19f711aba.php
所以,我就需要改寫自己的 Store Procedure ,改成透過 OPENROWSET
的方式來解決。於是將自己的程式改寫如下:
SET FMTONLY OFF關鍵字,宣告這個 Script 語法裡面是可以允許建立
暫存資料表的。
使用 C# 的 "as" 關鍵字
強迫轉型方式來處理。就以 Person 的類別來舉例:
class Person
{
public string Name = string.Empty;
public string ID = string.Empty;
public Person(string _name,string _id)
{
Name = _name;
ID = _id;
}
public override bool Equals(object obj)
{
Person p = (Person)obj;
return p.Name == this.Name && p.ID == this.ID;
}
}
會直接就用 (Person)去強迫轉型,原因是因為自己認為 obj 一定是屬於
Person型別,才會有如此的寫法。但是,真的能保證 obj 一定是屬於
Person型別嗎?這可能是自己的一廂情願吧!
的錯誤訊息。
的動作,如果成功,自然就會回傳轉型成功後的物件型別;如果失敗,則會
回傳 null。所以,當使用了 "as" 關鍵字後,在透過判斷回傳值是否為 null
來完成型別轉換工作。
{
Person p = obj as Person;
}
2009年9月20日 星期日
Overriding Equals
這兩個實體在記憶體分別儲存存在不同的位址,由此看來,這兩個實體的確
是不同的。
class Person
public Person(string _name,string _id)
}
Person 有兩個公開屬性,分別是 Name 與 ID。
如果程式如下:
Person p1=New Person("paladin","01");
Person p2=New Person("paladin","01");
這 p1 與 p2 ,雖然所傳入的值,都是 Name="paladin" ,ID="01",
但他們彼此卻是不相同的,可以透過以下的 Equals( )來知道。
p1.Equals(p2)
他會回傳 False。
然而,今天如果我們想要重新定義,只要是 Name 與 ID 相同,就要視
兩個實體為相同,可以嗎?
可以的,此時,可以透過覆寫 Equals( ) 來達成。
在 Person 類別裡,針對這個類別的 Equals( ) 方法進行覆寫,只要
Name 與 ID 相同,就視為相同的物件。
將 覆寫的程式描述如下:
public override bool Equals(object obj)
{
Person p = (Person)obj;
return p.Name == this.Name && p.ID == this.ID;
}
如此,執行 p1.Equals(p2) 時,
則會去比較 p2.Name 是否等於 p1.Name 且 p2.ID 是否等於 p1.ID ,
然後以此來回傳 Equals( ) 的值。
完整的 Person 的定義如下:
class Person
{
public string Name = string.Empty;
public string ID = string.Empty;
public Person(string _name,string _id)
{
Name = _name;
ID = _id;
}
public override bool Equals(object obj)
{
Person p = (Person)obj;
return p.Name == this.Name && p.ID == this.ID;
}
}
而在實際比較時,就可以發現,此時 p1.Equals(p2) 就會回傳 True 了
static void Main(string[] args)
{
Person p1 = new Person("paladin", "01");
Person p2 = new Person("paladin", "01");
Console.WriteLine(string.Format("p1 is the same with p2 ? {0}", p1.Equals(p2) ? "True" : "False"));
Console.ReadKey();
}
2009年9月11日 星期五
hammer & nail
在 IT 界也是常常看到這種現象。偶而出現一種程式語言、或一項產品,有些人就會冀望它能夠實現任何東西,就會期待他能有十八般武藝什麼功能都能做得到。若是如此,就不免落得「以井觀天」,不切實際了。