網頁

2012年9月28日 星期五

以預存程序做資料庫查詢

筆者曾在以具名參數實做資料庫新增修改刪除 文章中介紹了具名參數,及其應用的方法......

固然使用具名參數可以減低SQL Injection(SQL 隱碼)的風險,但要加強存取資料庫時的安全性,可以改用預存程序存取資料。
雖然微軟官方網站建立預存程序已經說明了如何使用SQL SERVER的預存程序,但SQL SERVER和MySQL的預存程序語法有些微差異,容易造成混淆,因此筆者將兩種資料庫預存程序列出語法作比較。

SQL SERVER版本:
//指定使用bookstore資料庫
USE bookstore;
GO

//建立select_books預存程序
CREATE PROCEDURE select_books

//定義傳入的具名參數名稱與資料型別,SQL SERVER以@辨別具名參數
@booksname varchar(50), 
 @booksprice int(10) 

//SQL SERVER以AS開始下SQL指令,以GO做結尾不需加分號(;) 
AS

//下SQL指令
SELECT booksname, booksprice 
 FROM books 
 WHERE booksname = @booksname AND booksprice = @booksprice 
GO


MySQL版本:
//MySQL預存程序建立在各資料庫內,因此無須宣告將使用的資料庫

//由root登入localhost建立select_books預存程序(MySQl為TCP/IP登入驗證) 
CREATE DEFINER=`root`@`localhost` PROCEDURE `select_books`

//定義傳入具名參數名稱的具名參數資料型別並用()區隔,
//MySQL具名參數中不可使用@,?等特殊符號,筆者使用相近的字詞作為具名參數名稱
(
p_booksname varchar(50),
 p_booksprice int(10) 
)

//MySQL以BEGIN開始下SQL指令,以END作結尾需加分號(;)
BEGIN 

//下SQL指令
SELECT booksname, booksprice
FROM books
WHERE booksname = p_booksname AND booksprice = p_booksprice;
END
從上面兩個範例看得出來,語法其實大同小異,但是差異頗多,在使用上要多加注意,不要用錯

2012年9月26日 星期三

以ADO.NET實體模型搭配EntityDataSource存取資料庫


今天保哥教了我一招 我才知道-原來ADO.NET實體資料模型也可以搭配EntityDataSource在WEBFORM上使用
步驟很簡單:
1. 建立一個ADO.NET實體模型
2.建立一個EntityDataSource
3. 設定EntityDataSource

接下來就能透過EntityDataSource來存取資料庫了!

EntityDataSource使用方式與SqlDataSource大同小異,都是透過設定精靈完成資料存取。
但兩者差異在於,後端資料庫不是搭配SQL SERVER時,透過SqlDataSource來存取資料庫將會產生語法的問題......
原因在於,SQL SERVER執行SQL指令時可以加入中括號而不影響結果,但如果資料庫使用MySQL卻會造成SERVER讀取指令錯誤無法執行。

筆者的資料庫系統就是使用MySQL,使用SqlDataSource存取資料時都需要自行指定SELECT,INSERT,UPDATE,DELETE指令,設定上也較複雜......
所以,筆者都是習慣寫程式碼 : 建立連線字串->建立連線->存取資料->將資料放到相對應表格 。但是這樣在作網站時會浪費很多時間在建立資料連接與存取上......

如果使用EntityDataSources呢?
很簡單,設定精靈設定完之後就能直接存取資料庫了,不用因為資料庫語法上的差異再做其他設定,甚至寫程式碼存取資料。

針對非SQL SERVER的開發環境EntityDataSource的確比較方便易用,但如果開發環境都是微軟自家產品時差別就不囉!(或許有,但筆者不確定)。

注:使用EntityDataSource時須注意,其所使用的SQL指令並非T-SQL,而是Entity SQL,使用上會有些微差異,範例如下:

account表中有四個欄位{id,pwd,mail,address},假設筆者要查詢account中所有欄位的資料-大家應該會用 * 來做查詢,但在Entity SQL中,例1指令將會發生錯誤,例2才可SELECT到資料
1. (X)SELECT * FROM account WHERE id = 'xyz';
2. (O)SELECT id,pwd,mail,address FROM account WHERE id  = 'xyz';
Entity SQL不可使用 "*"

微軟產品的電子書指南

今天在找學習資源時,發現MICROSOFT GULF COMMUNITY BLOG提供微軟相關產品的電子書指南,因此放上來與大家分享。
Large collection of Free Microsoft eBooks
雖然指南都是英文,但是並沒有很艱深的單字,因此請放心閱讀。

當然其中也有MVC4的電子書指南,想要好好了解MVC的話可以閱讀電子書,同時也可以從範例中做練習,對學習MVC會有很大幫助。

MVC4電子檔載點如下:Intro to ASP.NET MVC 4 with Visual Studio - Beta

另外,也提供一個MVC自學的網站ASP.NET MVC 自學日誌

以具名參數實做資料庫新增修改刪除


在C#中常會使用文字方塊來輸入資料到資料庫,但是這樣將會有SQL Injection(SQL隱碼)的危險。

當然,可以使用字元替換(TextBox1..Text.Replace)的方法,避免無聊人士胡亂輸入字元,
而筆者則是建議使用具名參數來達成相同的效果,如此一來可以避免掉許多的風險。

使用具名參數的流程可以分為五個部分:

1. 新增使用資料庫以及具名參數所需之Namespace(命名空間)
2. 宣告需使用的物件-SqlConnection及SqlCommand並給予初值
3. 開啟資料庫連線,並建立具名參數所使用的參數名稱,資料型別,並指定輸入的TextBox
4. 執行SQL指令
5. 關閉資料連線

以下為範例程式碼:
//1. 新增使用資料庫以及具名參數所需之Namespace(命名空間)
using System.Data.SqlClient;//引用資料庫所需的資料
using System.Data;//引用具名參數所需的資料
.
.
.
.
//-----------------------------------------------------------------

//2. 宣告連線並指定使用的資料庫名稱及登入帳號密碼
SqlConnection connect = new SqlConnection("server = localhost; uid = xxxx; pwd = yyyy; database = test;");

        //3.1 開啟資料連線
        connect.Open();

//----------------------------------------新增

//此SQL指令為新增table2的資料,資料表內id欄位所輸入的字串從TextBox而來
SqlCommand cmdInsert = new SqlCommand("INSERT INTO table2(id,name,content,date) VALUES (@id,@name,@content,@date)", connect);

//3.2 建立具名參數的參數名稱,並指定參數所要帶入的資料來自TextBox
cmdInsert.Parameters.Add("@id",SqlDbType.NVarChar).Value = TextBox1.Text;
cmdInsert.Parameters.Add("@name",SqlDbType.NVarChar).Value = TextBox2.Text;
cmdInsert.Parameters.Add("@content",SqlDbType.NVarChar).Value = TextBox3.Text;
cmdInsert.Parameters.Add("@date",SqlDbType.NVarChar).Value = TextBox4.Text;


        //4. 開啟資料庫執行SQL語法
        cmdInsert.ExecuteNonQuery();

//----------------------------------------修改

//此SQL指令為更新table2的資料,資料表內id欄位所輸入的字串從TextBox而來
SqlCommand cmdUpdate = new SqlCommand("UPDATE table2 SET name = @name, content = @content, date = @date WHERE id = @id",connect);

//3.2 建立具名參數的參數名稱,並指定參數所要帶入的資料來自TextBox
cmdUpdate.Parameters.Add("@id",SqlDbType.NVarChar).Value = TextBox1.Text;
cmdUpdate.Parameters.Add("@name",SqlDbType.NVarChar).Value = TextBox2.Text;
cmdUpdate.Parameters.Add("@content",SqlDbType.NVarChar).Value = TextBox3.Text;
cmdUpdate.Parameters.Add("@date",SqlDbType.NVarChar).Value = TextBox4.Text;


        //4. 開啟資料庫執行SQL語法
        cmdUpdate.ExecuteNonQuery();

//---------------------------------------刪除

//此SQL指令為刪除table2的某筆資料,TextBox1.Text輸入的字串為刪除依據
SqlCommand cmdDelete = new SqlCommand("DELETE FROM table2 WHERE id = @id",connect);

//3.2 建立具名參數的參數名稱,並指定參數所要帶入的資料來自TextBox
        cmdDelete.Parameters.Add("@id",SqlDbType.NVarChar).Value = TextBox1.Text;

        //4. 開啟資料庫執行SQL語法
        cmdDelete.ExecuteNonQuery();

        //5. 關閉資料連線
        connect.Close();