ADO.NET的記憶碎片(九)


這一篇是講復雜更新數據,在講復雜更新之前,我們要先將參數化查詢,今天我猛然發現,參數化查詢我真的之前沒有提到過,
不過在上篇中有用到參數化查詢,那我今天就正好把參數化的查詢這一塊內容整理出來,不要留下什么盲點。
參數化查詢
假設一種場景,希望獲得一位特定的用戶訂單信息,希望執行下面的SQL查詢:


**select OrderID,CustomerID,OrderDate,EmployeeID from Orders where CustomerID = @CustomerID


要在ADO.NET對象模型中執行一個參數化查詢,需要向Command對象的Parameters集合中添加Parameter對象。
參考代碼如下:

SqlCommand cmd = new SqlCommand();
cmd.Connection = new SqlConnection("連接字符串");
cmd.CommandText = "select OrderID,CustomerID,OrderDate,EmployeeID from Orders where CustomerID = @CustomerID";
SqlParameter p;
p = new SqlParameter();
p.ParameterName = "@CustomerID";
p.Value = "ALFKI";
cmd.Parameters.Add(p);

**使用語法糖

p = cmd.Parameters.AddWithValue("@CustomerID", "ALFKI");


*顯式設置數據類型
*有兩種方法可以對參數的類型進行設置:設置SqlParameter對象的SqlDbType屬性,或者在SqlParameter的構造函數中設置
*參考代碼如下:
構造函數中設置

p = new SqlParameter("@CustomerID",SqlDbType.NVarChar,5);
p.Value = "ALFKI";
cmd.Parameters.Add(p);

設置SqlParameter對象的SqlDbType屬性

p.SqlDbType = SqlDbType.NVarChar;
p.Size = 5;

*參數的方向
*在上面的類子中我們設置的參數都是輸入參數,還可以使用參數從數據庫中獲取數據。即是:使用輸出參數,返回結果,而且性能會更好
*假設使用輸入參數根據ProductName來查詢數據,並通過輸出參數來返回Price和InStock的值,SQL語句如下:
*select @Price = Price,@InStock = InStock from Products where ProductName = @ProductName
*參考代碼如下:

SqlCommand cmd2 = new SqlCommand();
cmd2.Connection = new SqlConnection("連接字符串");
cmd2.CommandText = "select @Price = Price,@InStock = InStock from Products where ProductName = @ProductName";
SqlParameter price,instock,productname;
price = cmd.Parameters.Add("@Price",SqlDbType.Money);
price.Direction = ParameterDirection.Output;
instock = cmd.Parameters.Add("@InStock", SqlDbType.NVarChar,20);
instock.Direction = ParameterDirection.Output;
productname = cmd.Parameters.Add("@ProductName", SqlDbType.NVarChar, 40);
productname.Value = "Chai";
cmd2.ExecuteNonQuery();
if (price.Value == DBNull.Value)
{
    Console.WriteLine("No found named {0}", productname.Value);
}
else
{
    Console.WriteLine("{0}--{1}", price.Value, instock.Value);
}

 復雜更新:提交更新后刷新一行
 在提交更新后刷新一行,因為有時間截列,可以保證數據不會被亂改,所以在提交更新后刷新一行是非常有必要的,
 我們的解決方法就是用輸出參數獲取新行數據,使用SQL語句是:

 update OrderDetailsWithTimestamp
    set OrderID = @OrderIDNew, ProductID = @ProductIDNew, Quantity = @QuantityNew, Price = @PriceNew
 where OrderID = @OrderIDOld and ProductID = @ProductIDOld and Timestamp = @TimestampOld
 if @@ROWCOUNT <> 0 then
 select @QuantityNew = Quantity,@PriceNew = Price, @TimestampNew = Timestamp
 from OrderDetailsWithTimestamp
 where OrderID = @OrderIDNew and ProductID=@ProductIDNew

 參考代碼如下:

cmd2.CommandText = "update OrderDetailsWithTimestamp" +
     "set OrderID = @OrderIDNew, ProductID = @ProductIDNew, Quantity = @QuantityNew, Price = @PriceNew" +
  "where OrderID = @OrderIDOld and ProductID = @ProductIDOld and Timestamp = @TimestampOld" +
  "if @@ROWCOUNT <> 0 then" +
  "select @QuantityNew = Quantity,@PriceNew = Price, @TimestampNew = Timestamp" +
  "from OrderDetailsWithTimestamp" +
  "where OrderID = @OrderIDNew and ProductID=@ProductIDNew";
SqlParameter QuantityNew, PriceNew, TimestampNew;

cmd2.Parameters.AddWithValue("@OrderIDNew", "OrderIDNew");
cmd2.Parameters.AddWithValue("@ProductIDNew", "ProductIDNew");
QuantityNew = cmd2.Parameters.AddWithValue("@QuantityNew", "QuantityNew");
QuantityNew.Direction = ParameterDirection.InputOutput;
PriceNew = cmd2.Parameters.AddWithValue("@PriceNew", "PriceNew");
PriceNew.Direction = ParameterDirection.InputOutput;
TimestampNew = cmd2.Parameters.AddWithValue("@TimestampNew", "TimestampNew");
TimestampNew.Direction = ParameterDirection.Output;
cmd2.Parameters.AddWithValue("@OrderIDOld", "OrderIDOld");
cmd2.Parameters.AddWithValue("@ProductIDOld", "ProductIDOld");
cmd2.Parameters.AddWithValue("@TimestampOld", "TimestampOld");

 QuantityNew, PriceNew, TimestampNew這三個輸出參數可以作為刷新數據來使用
 復雜更新:一次插入多條數據,使用SqlBulkCopy對象
 參考代碼:

 <summary>
向表插入數據
 <summary>
 <param name="table">在內存中的數據,即將要插入數據庫的數據<param>
 <param name="database">對應數據庫的名稱<param>
 <param name="database">對應數據庫的表名稱<param>

public static void InsertTableData(DataTable table, string database,string tableName)
{
    using (SqlBulkCopy bcp = new SqlBulkCopy("Server=.;database=;user id=;Password=;connection reset=false;"))
    {
        bcp.BatchSize = 100;//每次傳輸的行數
        bcp.DestinationTableName = tableName;//目標表
        bcp.WriteToServer(table);
    }
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM