2012年7月24日 星期二

複製資料到有自動增值欄位的資料表

我一直以為,在 SQL Server 複製資料表A 到資料表 B 不是件難事,直到遇到「有自動增值欄位的資料表」。

舉例來說,以下是兩個一模一樣的資料結構 TB1 與 TB2 :
CREATE TABLE [dbo].[TB1](
 [SN] [int] IDENTITY(1,1) NOT NULL,
 [SName] [nvarchar](50) NULL
) ON [PRIMARY]


CREATE TABLE [dbo].[TB2](
 [SN] [int] IDENTITY(1,1) NOT NULL,
 [SName] [nvarchar](50) NULL
) ON [PRIMARY]


當我執行
insert into TB2 select * from TB1
會遇到下面錯誤訊息:
位於資料表 'TB2' 的識別欄位其外顯值只有當使用了資料行清單且 IDENTITY_INSERT 為 ON 時才能指定。

為了能夠解決上述問題,必須暫時讓「有自動增值的欄位」變成沒有自動增值。可以到管理介面去變更資料表的定義,如下:(但記得匯完資料之後要記得改回去)

另外也可以透過程式來完成:
--表示在有自動增長欄位的情況下還允許新增
SET IDENTITY_INSERT  TB2 ON 

--要注意,不可以用 select * from TB1,
--必需詳細的指出欄位
insert into TB2 (SN,SName)
select SN,SName from TB1

--關閉在有自動增長欄位的情況下還允許新增
SET IDENTITY_INSERT  TB2 OFF 


需特別注意的地方有二:
一、透過 IDENTITY_INSERT ON/OFF 來完成
二、不可以用 select * from ,需明確指出各個欄位名稱,如 select SN, SName from

自己實際遇到的資料表內容,其實非常巨大。當我使用第一種方式去設定時,匯出資料沒問題,但當我要將「自動增長欄位」的欄位改回「是」的時候,SQL Server 就會跳出訊息,告訴我偵測到大量的資料,警告我會花很多時間,問我要不要等待,當然選要,結過,他跑一陣子之後就發出逾時的錯誤訊息而中斷工作,而自動增長欄位的設定也沒有改回去。遇到這情況,就一定得改用剛剛介紹的第二種方式來處理。


參考:
01:要將資料新增至有自動增值欄位的資料表中

2012年7月13日 星期五

物件為何要 new 完之後才可以使用?

關於「物件為何要 new 完之後才可以使用?」這個問題,我在 Java 的書上看到作者將程式語法搭配記憶體的配置,解釋的很清楚,也分享一下。

MyObj obj=new MyObj(10);

把上述語法拆開來,分成三個部份。

首先是: MyObj obj
宣告了 obj 這個變數,會在記憶體中,如下圖,先配置一塊空間給 obj。而這塊記憶體空間,目前是空的(null),所以我們現在並沒辦法存取 obj 裡的資料。

接著是: new MyObj(10)
這個動作,會在記憶體另外配置一塊空間,而參數10,也一併會寫入這塊記憶體空間。

最後是:MyObj obj = new MyObj(10);
將 MyObject 的記憶體位址(0x1a2b3c4d),寫到 obj 的記憶體空間裡。日後,從 obj 就可以存取 MyObject 這塊記憶體裡的資料了。



參考:
01:Java SE 6全方位學習

2012年7月6日 星期五

透過 jQuery 取得 Asp.Net 裡 CheckBoxList 被勾選的文字(二)



先前曾經在「透過 jQuery 取得 Asp.Net 裡 CheckBoxList 被勾選的文字」文章記錄了當時的解決方法,最近再次遇到同樣的問題,試著換另一種做法來處理。

CheckBoxList 在網頁上的原始碼如下:

<table id="cb" border="0">
<tr>
 <td><input id="cb_0" type="checkbox" name="cb$0" />
 <label for="cb_0">paladin</label>
 </td>
</tr><tr>
 <td><input id="cb_1" type="checkbox" name="cb$1" />
 <label for="cb_1">ltt</label>
 </td>
</tr><tr>
 <td><input id="cb_2" type="checkbox" name="cb$2" />
 <label for="cb_2">lee</label>
 </td>
</tr>
</table>


在上面程式可以發現,CheckBox 的內容,是由後面緊接著的 Label 來定義。這次透過 jQuery 所提供的 .next() 函數,去找到所挑選物件的下一個兄弟姊妹,剛好 Label 正是 CheckBox 的第一順位兄弟姊妹。換言之,只要利用:

$("#cb_0").next().text()

就可以得到第一個 CheckBox 的值 :「paladin」 了。而最初目的:透過 jQuery 取得 Asp.Net 裡 CheckBoxList 被勾選的文字,就可以改寫如下:

<script>
    function ShowData() {
        var str = "";
        $("input[type=checkbox]").filter(":checked").each(function () {
            str = str + $(this).next().text() + ',';
        });

        alert(str);
    }

    $(function () {

        $("input[type=checkbox]").click(function () {
            ShowData();
        });           
    });
</script>

比較起來,這個寫法似乎比過去的簡潔許多。

但如果 CheckBoxList 的 RepeatLayout 屬性設為 Flow,這方法是否依然可行呢? RepeatLayout=Flow 的 HTML Code 如下:
<span id="cb_flow">
 <input id="cb_flow_0" type="checkbox" name="cb_flow$0" />
 <label for="cb_flow_0">paladin</label><br />
 <input id="cb_flow_1" type="checkbox" name="cb_flow$1" />
 <label for="cb_flow_1">ltt</label><br />
 <input id="cb_flow_2" type="checkbox" name="cb_flow$2" />
 <label for="cb_flow_2">lee</label>
</span>

CheckBox 後面的第一個兄弟姊妹,正是我們所要的值,所以這方法依然還是行的通。
參考:
01:透過 jQuery 取得 Asp.Net 裡 CheckBoxList 被勾選的文字
02:.next()

2012年7月5日 星期四

jQuery 的 :checked 在 Opera 不正常



在 jQuery 裡,如果想要知道 checkbox 有幾個被選取,可以使用

$("input:checked").size()

但我發現這方法,適用於 IE、Firefox、Chrome ,卻不適用 Opera 瀏覽器。我試著用一段測試程式如下:


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
    <script>
        function DoCheck() {
            alert($("input:checked").size());            
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <input type="button" id="btn" value="check" onclick="DoCheck();" />
    <div>
    <input id="cb1" type="checkbox" name="cb"  />111 <br />
    <input id="cb2" type="checkbox" name="cb"  />222 <br />
    <input id="cb3" type="checkbox" name="cb"  />333 <br />
    </div>
    </form>
</body>
</html>

在 Opera 測試時,任意更改 checkbox 的選取組合,會發現 alert($("input:checked").size()); 所得到的結果,竟然會出錯,一開始還以為自己眼花,但沒想到是真的。在 jQuery 的 BUG TRACKER,可以看到目前已經有人提出同樣的問題了。

慶幸的,是目前還有一個各個瀏覽器都還支援的寫法:

$("input").filter(":checked").size()

所以,在 jQuery 尚未提出修正之前,還必須先以 .filter() 的方式來取代。

Opera 版本:11.62
jQuery 版本:1.7.2

2012年7月4日 星期三

UrlPathEncode 用於檔案下載出現亂碼的問題

近日在閱讀 郝冠軍 所著的「ASP.NET本質論」,裡面提到了有關 UrlEncode 與 UrlPathEncode 的差別。我對於裡面有關 UrlPathEncode 的定義比較有興趣,因為他寫著:

UrlEncode 首先使用回應中的編碼對內容進行編碼,編碼後的字節數組再看成是ASCII 字符,
其中A~Z、a~z、0~9、-、_、.、!、*、\、 (、) 被認為是安全的字符,不需要特殊編碼。
其他字符需要經過字符編碼,空格被編碼為+,剩下的被編碼為% 引導的十六進製表示方法。

UrlPathEncode 僅僅編碼Url 的Path 部分
UrlPathEncode 首先使用UTF8 編碼對字符串進行轉換,將轉換後的結果看成ASCII 串,然後,
將其中的空格替換為%20。

但自己實際上去實作一下發現下面結果:

一、輸入字串來源是 URL :http://paladinprogram.blogspot.tw/index.aspx?q=心 亞.jpg
UrlEncode →http%3a%2f%2fpaladinprogram.blogspot.tw%2findex.aspx%3fq%3d%e5%bf%83+%e4%ba%9e.jpg
UrlPathEncode →http://paladinprogram.blogspot.tw/index.aspx?q=心 亞.jpg

二、輸入字串來源非 URL :心 亞.jpg
UrlEncode →%e5%bf%83+%e4%ba%9e.jpg
UrlPathEncode →%e5%bf%83%20%e4%ba%9e.jpg

UrlPathEncode 如果是針對 URL 字串,則只會對 Path 的部份進行處理,但如果非字串的話,則全部都會被編碼。在編碼的時候,遇到空白字元的處理上,UrlEncode 是把他用 + 來取代,而 UrlPathEncode 則是用 %20 來取代。

接著,該書的作者,透過 UrlPathEncode 對空白編碼處理的特性,把他應用在處理檔案下載時,檔案名稱是亂碼的問題。可以參考:编码与解码。這方法在 IE 、 Chrome 上可以完美解決,但是在 FireFox 上卻還是不行。於是再翻出自己以前所整理過的一篇文章「檔案下載或開啟時出現亂碼檔名」,看看現在會不會激發出新的解法,蠻慶幸地,又有另一種解法可以選擇了。

這次處理亂碼檔名的過程中,有了 2 個方向去處理:
1.各家瀏覽器,如果下載檔名直接給他中文,除了 IE 之外,其餘都可以正常。所以使用區別瀏覽器的作法。
2.對於下載檔名,如果名字中間有空白,FireFox 會發生截斷的現象,但是透過引號將檔名包起來,則可以正常[ ref:檔案下載solution]。

於是新的寫法如下:

protected void btnDownload_Click(object sender, EventArgs e)
{
    string str = "江 苏.doc";
    if (Context.Request.Browser.Browser == "IE")
        str = Context.Server.UrlPathEncode(str);
    else
        str = string.Format("\"{0}\"", str);
          
    Context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", str));
            
}


與先前舊寫法最大的不同,就是屏棄了

Response.HeaderEncoding = System.Text.Encoding.GetEncoding("big5");

的寫法,打破了僅支援繁體中文的限制了。

測試程式:下載

參考:
01:ASP.NET本質論
02:编码与解码
03:檔案下載或開啟時出現亂碼檔名
04:檔案下載solution

2012年7月3日 星期二

清除 Visual Studio 的 Recent Projects


在 Visual Studio 開發環境中,每次一啟動就會跑出 Recent Projects,他列出了最近所開發的幾筆專案。但有時候,連自己隨意測試的專案或是過期不想要的專案都還是一直列在上面,看了礙眼卻又不知道怎麼把他移除。

剛好於「How to remove recent projects from Visual Studio Start Page」找到不錯的方法,就是直接去修改 Registry。

1.先關閉目前已開啟的 Visual Studio
2.在開始的命令列,執行  regedit editor
3.在登錄編輯程式,找到

(適用於 VS2005)
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList


(適用於 VS2008)
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\ProjectMRUList



(適用於 VS 2010)
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\ProjectMRUList

並將其 Delete,即可將不需要的專案刪除即可。

參考:
01:How to remove recent projects from Visual Studio Start Page
02:How do you REMOVE or DELETE Items from Recent Projects list in VS2005 RC?

2012年7月1日 星期日

觀功念恩的二個層次


週六下午的共學課程,有個主題是「念父母恩分享及回饋」。鵬伍師姊在現場播放了「母親的勇氣」電視廣告,影片中,表達了父母對子女的:堅忍、勇敢、愛。這段影片,彷彿就像一隻溫暖的手,撥弄著每個人感動的心弦。

自己在音樂「Goodbye Police」出來時,也開始無法忍住...

在如亨法師的三合一教授裡有提到,我們常常說要對同行、親人做「觀功念恩」,但你真的有做對嗎?在此,法師將我們的觀功念恩分為兩個層次:一個是虛弱無力,一個是對我有何饒益、對我有何啟發。

先說說第一個層次:虛弱無力。

「我看到一位師兄,很會消文,很精進,好隨喜這位師兄喔。」

法師認為,這種觀功念恩是非常薄弱的,更恐怖的,是他很容易變成觀過念怨。為什麼呢?如果今天你心情好,自然會很隨喜這位師兄,但如果你今天心情不好,或 是在趕時間,同樣的事情,就會變成:「這位師兄話很多,每次都講好久,讓我們的進度都往後延」。自己細細思索,的確表面上是對別人觀功念恩,但效果其實是 很局限、很表面。法師也提到,這種觀功念恩,是屬於「應酬式」的觀功念恩。

第二個層次:對我有何饒益、對我有何啟發?

當你看到很會消文的師兄後,開始反省自己,有沒有辦法去效學他,每天多花些時間來研讀廣論,或是透過共學的方式來提昇自己。

在小組討論中,我舉了一個例子。譬如今天看到一位師姊桌上放了一瓶里仁有機豆漿,如果我是用虛弱無力的觀功念恩,可能就會是:

「哇!好隨喜師姊護持了里仁有機食品ㄟ!」

如果今天剛好意念不夠清淨,起了比較心,可會跑出下面幾句:

「現在一瓶多少?...80 ?喔喔,我在大潤發看到的豆漿都比這便宜好多,有機食品真的貴森森」

如此的對話應答,真的是觀功念恩嗎?

在第二種層次,去思維自己看到別人的功德,對自己有何饒益,有何啟發。那可能就會變成:

看到有機豆漿,就會想到那群在有機環境下快樂工作的農夫,還有在那生存的許許多多的有情眾生,這些環境能夠得以保留,是師父當初的堅持,完全是對萬物眾生 的慈悲,對這片土地的感恩,這願力是多麼的宏大啊!佛陀幾千年前所說過的話,所傳承的教法,至今都還饒益著我們,指引著我們。今天我也要以行動去支持,去 護持,去里仁買一瓶有機豆漿。

的確,如果我們的觀功念恩,都能用第二個層次去實踐,對於自己的影響與啟發,實在是多很多。