Thursday, February 16, 2012

[.NET] XML 說明檔建立


範例
/// <summary>呼叫此方法做資料庫連線</summary>
/// <param name="sDataSource">資料庫主機名稱或位址</param>
/// <param name="sCatalog">預設資料庫目錄</param>
/// <param name="sUserId">登入帳號</param>
/// <param name="sPwd">登入密碼</param>
public static bool DBModule_Init(String sDataSource, String sCatalog, String sUserId, String sPwd)
{
   //….
}


然後到專案屬性的[建置],把輸出的「XML文件檔案」勾選起來,再建置一次就可以了。


Monday, February 13, 2012

轉換ASP.net程式到4.0...出現的錯誤訊息~

今天測試從framework 2.0升到 4.0的ASP.net網站,
在reload 樹狀結構的時後,跳出一個錯誤訊息:



型別 'System.Web.UI.ScriptManager' (來自組件 'System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35') 中的方法 'get_EnableCdn' 沒有實作。


查了Google之後,解決的方式是將
web.config中所有的System.Web.Extensions, Version=3.5.0.0全部都改成System.Web.Extensions, Version=4.0.0.0就可以了。

參考文章:

Saturday, February 4, 2012

寫ADO.NET程式的小建議

這幾天小弟被要求要去對報表的數字是否正確,其實我心裡是千百個不願意~
一來對數字,我認為是USER的職責,
二來是報表的程式,註解少到用手指頭都算得出來,
小弟最討厭看這種不寫註解的程式。

果不其然,當報表數字有問題時,回去看程式的SQL追問題時,因為程式不易閱讀,讓小弟看的很痛苦。 以下是幾點建議。

1. 一個Sql可以完成的事,不必用兩個Sql

比如,我們要去更新表格A的總消費金額欄位(CONSUME_AMT),你會選擇 :
 (a) 先下 Select A.CONSUME_AMT from A , 取出總金額到變數X,
       然後 X = X+新消費金額, 再 UPDATE A set CONSUME_AMT=X 。
 (b) 直接下 UPDATE A set CONSUME_AMT= (CONSUME_AMT+ 新消費金額)

 這樣一看很明顯~~當然是選 (b)!!
 這支程式很多Insert和Update都是用(a) ... 這樣也算了,但是它還犯了下面這個錯誤...



2. 避免直接拿DataTable.Rows[0][X]來組Sql:

假設我們有多個來源表格: A, B , 要把A, B的某些欄位放到C

第一個Sql  : SELECT X, Y, Z ... FROM A

把結果放到 DataTable_A ~

第二個Sql : SELECT S, T, U ... FROM B

把結果放到 DataTable_B ~

然後Insert的Sql寫成這樣 :

String iSql = "INSERT INTO C (col02, col05, col01, ... )" +
                     "VALUES ( '"+ DataTable_A.Rows[0][15].ToString() +"','" +
                                               DataTable_B.Rows[0][11].ToString() +"','" +
                                               DataTable_B.Rows[0][0].ToString() +"','" +
                                               DataTable_A.Rows[0][10].ToString() +"','" +
                                               ... );


好的,我們現在發現表格C的某個欄位有問題,我們要回去找來源的資料,
問題來了,我們會先去找iSql,找出對應的欄位值是 DataTable_A.Rows[0][10].ToString() ,
然後我們再回到 第一個Sql,開始去找這第十個欄位是哪一個A的欄位!!! 
如果沒有整理好的DB schema,會超級浪費時間!!

如果多寫幾行程式碼:
DataRow dr_A = DataTable_A.Rows[0];
String sC_COL_01 = dr_A["X"].ToString();
String sC_COL_02 = dr_A["Y"].ToString();
 ....

String iSql = "INSERT INTO C (col02, col05, col01, ... )" +
                     "VALUES ( '"+ sC_COL_02 +"','" +
                                              sC_COL_05  +"','" +
                                               sC_COL_01 +"','" +
                                               ... );

要找C的某欄位,可以馬上找到對應的欄位值為 sC_COL_XX,
由sC_COL_XX是不是很快可以知道是從哪一個表格的哪一個欄位帶過來的嗎?
是不是節省了很多時間呢?

而且sC_COL_XX這些變數,都可以重複再使用~~ 


(待續...)

Wednesday, February 1, 2012

[Oracle] Select SQL Tuning 查詢效能調整(轉錄)

轉錄自:http://tomkuo139.blogspot.com/2009/08/oracle-select-sql-tuning.html

1. 建立 Index Key
2. Where 條件中, 是否用函數
3. Where 條件中, 是否使用 In / Not In / Exists

... 更多請參考原文

[Sql Server] MERGE語法教學

MERGE語句是Oracle9i新增的語法,用來合併UPDATE和INSERT語句。
通過MERGE語句,根據一張表或子查詢的連接條件對另外一張表進行查詢,
連接條件匹配上的進行UPDATE,無法匹配的執行INSERT。
這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE。

PS. 也適用於Microsoft Sql Server 2008以上版本

範例:
兩個表格JB_BUYLIST_T(購物清單), JB_LSTBUY_D(紀錄最後一次買的東西)
我們現在要做的事情是…
抓出每個人購物清單中最後一次買的東西,然後把它更新或新增到JB_LSTBUY_D這邊。

Step1.建立表格
/*購物清單*/
CREATE TABLE JB_BUYLIST_T
(
ID       VARCHAR(10),
ITEM     VARCHAR(20),
BUY_TIME VARCHAR(8)
);

/*紀錄最後一次買的東西*/
CREATE TABLE JB_LSTBUY_D
(
ID           VARCHAR(10),
LST_BUY_ITEM VARCHAR(20)
);

Step2.先新增三筆購物清單
INSERT INTO JB_BUYLIST_T VALUES('JB','雜誌','20110701');
INSERT INTO JB_BUYLIST_T VALUES('JB','飯糰','20110703');
INSERT INTO JB_BUYLIST_T VALUES('D12','便當','20110702');


Step3. 執行MERGE語法

MERGE INTO JB_LSTBUY_D a USING
(
           SELECT ID,ITEM
           FROM
           (
                     SELECT
                     RANK() OVER (PARTITION BY ID ORDER BY BUY_TIME DESC) as RNK,
                     ID,
                     ITEM
                     FROM JB_BUYLIST_T
           ) X 

WHERE RNK=1

) b
ON
(
a.ID = b.ID -- AND ... 如果還有其它條件
)
WHEN MATCHED THEN UPDATE SET a.LST_BUY_ITEM = b.ITEM
WHEN NOT MATCHED THEN INSERT VALUES (b.ID, b.ITEM);


PS. b裡面是利用RANK()挑出每人最後一筆購物品。

   藍色→目標表格

   綠色→來源表格
   紅色→固定寫法



結果成功新增兩筆資料到 JB_LSTBUY_D :



Step4. 我們接下來試看看能不能同時做更新和新增…

INSERT INTO JB_BUYLIST_T VALUES('JB','飲料','20110705');
INSERT INTO JB_BUYLIST_T VALUES('D12','飲料','20110705');
INSERT INTO JB_BUYLIST_T VALUES('YOYO','飲料','20110705');
目前清單如下圖




Step5. 再執行步驟3的Merge語法,結果如下 (成功更新原本的兩筆資料 和 新增一筆資料):