轉自:http://www.cnblogs.com/oneword/archive/2010/09/10/1823414.html
連接到數據源
連接到數據源需要使用兩步:
1.創建連接字符串
2.使用Connection通過連接字符串進行連接
例1:
//使用連接字符串 //注意引用System.Data.Common 和 System.Data.SqlClient string connectionString = "server=.;database=DataBaseST;uid=sa;pwd=s1s1s1"; DbConnection connection = new SqlConnection(connectionString);
一般來說,我們不會在每個頁面都自定義一個連接字符串,然后再使用該字符串.如果某天需要修改該連接時,將會非常麻煩,所以我們將該字符串放入web.config,然后通過從該文件中獲取連接信息.
例2:
web.config中配置如下:
<connectionStrings> <add name="dbstconnectionstring" connectionString="Data Source=.;Initial Catalog=databasest;Persist Security Info=True;User ID=sa;password=s1s1s1"providerName="System.Data.SqlClient"/> </connectionStrings>頁面調用如下:
//注意引用System.Data.Common //注意引用System.Data.SqlClient string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection connection = new SqlConnection(connectionString);
此處需要注意的是:
連接字符串中的server,database,uid是必不可少的,如果有密碼,則pwd也不可少.
注意引用命名空間
可參見以下網站,提供眾多連接字符串格式:
創建命令
創建對象使用Command對象.Command對象是一個Sql語句或存儲過程的引用.Command對象可以被直接引用.
如何創建Command對象?見下例:
//創建Command有以下兩種方式 //方式一 // 通過Connection創建 DbCommand cmd1 = connection.CreateCommand(); //方式二 // 創建Command實例,再制定Connection DbCommand cmd2 = new SqlCommand(); cmd2.Connection = connection;
Command對象有以下重要屬性:
屬性 描述 CommandType 命令類型.
值為枚舉類型,有以下值:
Text:Sql腳本命令,默認值.
StoredProcedure:存儲過程
TableDirect:表的名稱(用的比較少)CommandText Sql語句或存儲過程的名字 Parameters 命令的參數 Command對象有以下重要方法:
方法 描述 ExecuteScalar 返回一個唯一的值 ExecuteNonQuery 用於更新或修改數據庫結構,返回被影響行數 ExecuteReader 返回數據行的集合
執行命令
通過對Command對象設定CommandType類型和CommandText,我們就可以通過上述方法來執行Command命令.
我們以下表,表結構如下:
表中數據如下:
- 我們首先演示ExecuteScalar方法,該方法用於返回結果集中的第一行的第一列;如果結果集為空,則為空引用.
請看以下示例:
string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection connection = new SqlConnection(connectionString); connection.Open(); DbCommand cmd = connection.CreateCommand(); //默認情況,Command對象的CommandType屬性為Text cmd.CommandText = "select count(*) from Employee"; string result = cmd.ExecuteScalar().ToString(); Response.Write(result); connection.Close();
- 下面再來看ExecuteNonQuery方法的使用,該方法可執行INSERT、DELETE、UPDATE 及 SET 語句等命令.
看以下示例:
string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection connection = new SqlConnection(connectionString); connection.Open(); DbCommand cmd = connection.CreateCommand(); //默認情況,Command對象的CommandType屬性為Text //現在,我們設置Command對象的CommandType屬性為StoredProcedure cmd.CommandType = CommandType.StoredProcedure; //此時Command對象的CommandText屬性為存儲過程名稱 cmd.CommandText = "InsertEmployee"; int result = cmd.ExecuteNonQuery(); Response.Write(result); connection.Close();
使用存儲過程InsertEmployee內容如下:
ALTER PROCEDURE dbo.InsertEmployee AS /* SET NOCOUNT ON */ insert into Employee (EmployeeName,EmployeeAge,EmployeeDeparmentID,EmployeeScore) values ('周?九?',27,1,85) RETURN
運行后,表內容如下,增加了一條新數據:
- 最后來看ExecuteReader方法的使用
ExecuteReader使用Transact-SQL的 sp_executesql 系統存儲過程調用命令.
該方法返回一個DataReader對象.DataReader是一個只讀的、前向的數據行的流.
DataReader對象有以下常用屬性和方法:
屬性或方法 類別 描述 Item 屬性 Read 方法 Sql語句或存儲過程的名字 GetXXX 方法 獲取值,其中XXX指String,Int32等等 GetValues 方法 一次性獲取當前所有的列 IsDbNull 方法 測試當前值是否為Null Close 方法 當Read返回為false時,應及時關閉DataReader,釋放連接 例1:
string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection connection = new SqlConnection(connectionString); connection.Open(); DbCommand cmd = connection.CreateCommand(); //默認情況,Command對象的CommandType屬性為Text cmd.CommandText = "select * from Employee"; DbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { //reader讀取數據時,列從0開始編號,故EmployeeID為第0列,EmployeeName為第1列 //讀取數據時采用了3種方式: // 1.因EmployeeName列為string類型,所以可以使用GetString方法 // 2.采用Item方式 // 3.采用GetValue方法 //語句中使用了IsDbNull方法來判斷分數欄是否為空 Response.Write(string.Format("Name:{0} Age:{1} Score:{2}<br/>", reader.GetString(1), reader["EmployeeAge"], reader.IsDBNull(4) ? "無" : reader.GetValue(4))); } //先關閉Reader reader.Close(); //再關閉Connection connection.Close();DataReader可以返回多個數據集結果,可使用NextResult方法移到下一個結果集,見下例.
例2:
protected void Page_Load(object sender, EventArgs e) { string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; DbConnection connection = new SqlConnection(connectionString); connection.Open(); DbCommand cmd = connection.CreateCommand(); //默認情況,Command對象的CommandType屬性為Text cmd.CommandText = "select top 2 * from Employee;select top 3 * from Employee"; DbDataReader reader = cmd.ExecuteReader(); Read(reader); Response.Write("<hr>"); reader.NextResult(); Read(reader); //先關閉Reader reader.Close(); //再關閉Connection connection.Close(); } void Read(DbDataReader reader) { while (reader.Read()) { //reader讀取數據時,列從0開始編號,故EmployeeID為第0列,EmployeeName為第1列 //讀取數據時采用了3種方式: // 1.因EmployeeName列為string類型,所以可以使用GetString方法 // 2.采用Item方式 // 3.采用GetValue方法 //語句中使用了IsDbNull方法來判斷分數欄是否為空 Response.Write(string.Format("Name:{0} Age:{1} Score:{2}<br/>", reader.GetString(1), reader["EmployeeAge"], reader.IsDBNull(4) ? "無" : reader.GetValue(4))); } }
結果:
使用參數
- 介紹
Sql語句和存儲過程可以有輸入輸出參數以及返回值
例如,我們在添加雇員信息時,雇員信息都是由用戶輸入進去的,而不是由系統內部設定的.
- 如何實現?
使用Command的Parameters可以實現我們向其中添加參數.
注意:
參數類型可以由Direction來設置,該屬性值為一個枚舉類型,取值如下:
ParameterDirection取值 描述 對應C# 對應SQL Input 輸入 InputOutput 輸入輸出 ref 對應output Output 輸出 out ReturnValue 返回值
- 例子
string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; //注意: // 此處換為SqlConnection,原來為DbConnection SqlConnection connection = new SqlConnection(connectionString); //注意: // 此處換為SqlCommand,原來為DbCommand SqlCommand cmd = connection.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "InsertEmployee"; //添加參數的幾種寫法 cmd.Parameters.Add("@EmployeeName",SqlDbType.NVarChar).Value = "測試用戶"; cmd.Parameters.Add(new SqlParameter("@EmployeeAge", 30)); //推薦使用AddWithValue方法 cmd.Parameters.AddWithValue("@EmployeeDepartmentID", 1); cmd.Parameters.AddWithValue("@EmployeeScore", 95); cmd.Parameters.Add(new SqlParameter("@outValue", SqlDbType.NVarChar, 20)); cmd.Parameters["@outValue"].Direction = ParameterDirection.Output; connection.Open(); int returnValue= cmd.ExecuteNonQuery(); Response.Write("ReturnValue:" + returnValue + "<br/>"); string result = cmd.Parameters["@outValue"].Value.ToString(); Response.Write("outValue:" + result); connection.Close();
存儲過程InsertEmployee內容如下:
ALTER PROCEDURE dbo.InsertEmployee ( @EmployeeName nvarchar(20), @EmployeeAge int=null, @EmployeeDepartmentID int=null, @EmployeeScore int=null, @outValue nvarchar(20) output ) AS /* SET NOCOUNT ON */ if exists(select * from Employee where EmployeeName=@EmployeeName) begin set @outValue='用戶名重復' return end insert into Employee (EmployeeName,EmployeeAge,EmployeeDeparmentID,EmployeeScore) values (@EmployeeName,@EmployeeAge,@EmployeeDepartmentID,@EmployeeScore) set @outValue='成功!' return
目前數據庫中並沒有"測試用戶"這樣一個用戶.
第一次運行時,結果如下:
ReturnValue:1 outValue:成功!
第二次運行時:結果如下:
ReturnValue:-1 outValue:用戶名重復
實現事務
事務是一系列相互關聯的任務,作為一個整體成功提交或失敗(提交或回滾).
事務的特性:
Atomicity(原子):事務或者全部提交,或者全不提交
Consistency(一致):事務保證了數據的完整性
Isolation(分離):事務處理了數據操作的並發性
Durability(持續):即使在事務結束后,發生系統崩潰等災難性情況,事務涉及的數據操作也將正常保存
先看使用Sql來實現事務.還是看例子來理解,我們現在新增一個表:Bank.
表結構如下:
表內容如下:
現在,我們向表中添加一系列的用戶,因為CustomerName是主鍵,所以不能重復.看下例:
string[] customerList = new string[] { "小張", "小王", "李四", "小趙" }; string connectionString = ConfigurationManager.ConnectionStrings["dbstconnectionstring"].ConnectionString; SqlConnection connection = new SqlConnection(connectionString); connection.Open(); SqlTransaction transaction = connection.BeginTransaction(); SqlCommand cmd = connection.CreateCommand(); cmd.Transaction = transaction; try { foreach (string customer in customerList) { cmd.CommandText = "insert into bank(customername,customermoney) values ('" + customer + "',0)"; cmd.ExecuteNonQuery(); } transaction.Commit(); } catch { transaction.Rollback(); } finally { connection.Close(); } }在運行代碼時,我們打開SqlServer事件查看器,看到以下結果:
exec sp_reset_connection go SET TRANSACTION ISOLATION LEVEL READ COMMITTED;BEGIN TRANSACTION go insert into bank(customername,customermoney) values ('小張',0) go insert into bank(customername,customermoney) values ('小王',0) go insert into bank(customername,customermoney) values ('李四',0) go IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION go
結果是數據表中沒有任何數據被增加.
現在我們將customerList中的"李四"用戶去掉.再來看來SqlServer事件查看器中的結果:
exec sp_reset_connection go SET TRANSACTION ISOLATION LEVEL READ COMMITTED;BEGIN TRANSACTION go insert into bank(customername,customermoney) values ('小張',0) go insert into bank(customername,customermoney) values ('小王',0) go insert into bank(customername,customermoney) values ('小趙',0) go COMMIT TRANSACTION go
數據庫Customer表的內容如下:
小結
- 使用Connection創建數據庫連接
- 使用Command創建命令
- 使用ExecuteScalar,ExecuteNonQuery,ExecuteReader方法來執行命令
- 使用DataReader來讀取數據
- 使用Command對象的Parameters屬性來添加參數
- 使用Connection對象來創建Transaction事務