使用以 SqlDataSource 進行的參數化查詢 (VB)
在本教學課程中,我們將繼續探討 SqlDataSource 控制項,並了解如何定義參數化查詢。 參數可以透過宣告方式和程式設計方式指定,並且可以從多個位置提取,例如查詢字串、工作階段狀態、其他控制項等。
簡介
在上一教學課程中,我們了解如何使用 SqlDataSource 控制項直接從資料庫檢索資料。 使用設定資料來源精靈,我們可以選擇資料庫,然後選擇要從資料表或檢視傳回的列;輸入自訂 SQL 陳述式;或使用預存程序。 無論是從資料表或檢視中選取列或輸入自訂 SQL 陳述式,SqlDataSource 控制項的 SelectCommand
屬性都會指派產生的臨機操作 SQL SELECT
陳述式,而在呼叫 SqlDataSource 的 Select()
方法 (以程式設計方式)時,執行的正是此 SELECT
陳述式。
上一個教學課程示範中使用的 SQL SELECT
陳述式缺少 WHERE
子句。 在 SELECT
陳述式中,WHERE
子句可用來限制傳回的結果。 例如,要顯示價格超過 50.00 美元的產品名稱,我們可以使用以下查詢:
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
通常,WHERE
子句中使用的值由某些外部來源決定,例如查詢字串值、工作階段變數或來自頁面上 Web 控制項的使用者輸入。 理想情況下,此類輸入是透過使用參數來指定的。 對於 Microsoft SQL Server,參數使用 @parameterName
表示,如下所示:
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
SqlDataSource 支援參數化查詢,包括 SELECT
陳述式,以及 INSERT
、UPDATE
和 DELETE
陳述式。 此外,參數值可以自動從各種來源 (查詢字串、工作階段狀態、頁面上的控制項等) 提取,也可以透過程式設計方式指派。 在本教學課程中,我們將了解如何定義參數化查詢,以及如何以宣告方式和程式設計方式指定參數值。
注意
在上一篇教學課程中,我們將 ObjectDataSource (我們在前 46 個教學課程中選擇的工具) 與 SqlDataSource 進行了比較,並指出它們概念上的相似之處。 這些相似之處也延伸到參數上。 ObjectDataSource 的參數會對應到商務邏輯層中方法的輸入參數。 使用 SqlDataSource,參數直接在 SQL 查詢中定義。 這兩個控制項都具有其 Select()
、Insert()
、Update()
和 Delete()
方法的參數集合,並且都可以從預定義來源 (查詢字串值、工作階段變數等) 填入這些參數值,或以程式設計方式指派這些參數值。
建立參數型查詢
SqlDataSource 控制項的設定資料來源精靈提供了三種途徑來定義要執行的命令,以擷取資料庫記錄:
- 透過從現有表或檢視中選擇列,
- 透過輸入自訂 SQL 陳述式,或
- 透過選擇儲存過程
從現有資料表或檢視中選取資料列時,必須透過「新增 WHERE
子句」對話方塊指定 WHERE
子句的參數。 但是,在建立自訂 SQL 陳述式時,您可以將參數直接輸入到 WHERE
子句中 (使用 @parameterName
來表示每個參數)。 預存程序由一個或多個 SQL 陳述式組成,這些陳述式可以參數化。 但是,SQL 陳述式中使用的參數必須作為輸入參數傳遞到預存程序。
由於建立參數化查詢取決於如何指定 SqlDataSource 的 SelectCommand
,因此讓我們來看看以下三種方法。 首先,打開 SqlDataSource
資料夾中的 ParameterizedQueries.aspx
頁面,將 SqlDataSource 控制項從工具箱拖曳到設計工具上,並將其 ID
設為 Products25BucksAndUnderDataSource
。 接著,請按一下控制項智慧標籤的「設定資料來源」連結。 選擇要使用的資料庫 (NORTHWINDConnectionString
),並按一下「下一步」。
步驟 1:從資料表或檢視中選取列時新增 WHERE 子句
當使用 SqlDataSource 控制項選擇要從資料庫傳回的資料時,「設定資料來源」精靈可讓我們簡單地選擇要從現有資料表或檢視傳回的列 (請參閱圖 1)。 這樣做會自動建立一個 SQL SELECT
陳述式,該陳述式是在叫用 SqlDataSource 的 Select()
方法時,傳送到資料庫的陳述式。 正如我們在上一教學課程中所做的那樣,從下拉式清單中選擇 Products 表,並檢查 ProductID
、ProductName
和 UnitPrice
列。
圖 1:選擇要從資料表或檢視傳回的列 (點擊查看完整圖片)
若要在 SELECT
陳述式中包含 WHERE
子句,請按一下 WHERE
按鈕,這將開啟「新增 WHERE
子句」對話方塊 (請參閱圖 2)。 若要新增參數來限制 SELECT
查詢傳回的結果,請先選擇用於篩選資料的列。 接下來,選擇用於篩選的運算子 (=, <、<=、> 等)。 最後,選擇參數值的來源,例如從查詢字串或工作階段狀態中取得。 設定參數後,按一下「新增」按鈕,將其包含在 SELECT
查詢中。
在本例中,我們只傳回 UnitPrice
值小於或等於 $25.00 的結果。 因此,從「列」下拉式清單中選擇 UnitPrice
,並從「運算子」下拉式清單中選擇「<=」。 當使用硬式編碼參數值 (例如 $25.00) 或要以程式設計方式指定參數值時,請從「來源」下拉式清單中選擇「無」。 接下來,在「值」文字輸入框 25.00 中輸入硬式編碼參數值,然後按一下新增按鈕完成該過程。
圖 2:限制從「新增 WHERE
子句」對話方塊傳回的結果 (點擊查看完整圖片)
新增參數後,按一下「確定」傳回「設定資料來源」精靈。 精靈底部的 SELECT
陳述式現在應包含一個帶有名為 @UnitPrice
的參數的 WHERE
子句:
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
注意
如果您在「新增 WHERE
子句」對話方塊中的 WHERE
子句中指定多個條件,精靈將使用 AND
運算子將它們連接起來。 如果您需要在 WHERE
子句中包含 OR
(例如 WHERE UnitPrice <= @UnitPrice OR Discontinued = 1
),那麼您必須透過自訂 SQL 陳述式畫面建構 SELECT
陳述式。
完成 SqlDataSource 的設定 (按一下「下一步」,然後按一下「完成」),然後檢查 SqlDataSource 的宣告式標記。 標記現在包含 <SelectParameters>
集合,它詳細說明了 SelectCommand
參數的來源。
<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
<SelectParameters>
<asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
</SelectParameters>
</asp:SqlDataSource>
當呼叫 SqlDataSource 的 Select()
方法時,UnitPrice
參數值 (25.00) 將在傳送至資料庫之前套用至 SelectCommand
中的 @UnitPrice
參數。 最終結果是,只有小於或等於 25.00 美元的產品才會從 Products
表中傳回。 若要確認這一點,請將 GridView 新增至頁面,將其繫結至此資料來源,然後透過瀏覽器檢視頁面。 您應該只能看到列出的那些小於或等於 25.00 美元的產品,如圖 3 所示。
圖 3:僅顯示小於或等於 25.00 美元的產品 (點擊查看完整圖片)
步驟 2:為自訂 SQL 陳述式新增參數
新增自訂 SQL 陳述式時,您可以明確輸入 WHERE
子句,或在查詢產生器的篩選器儲存格中指定值。 為了示範這一點,讓我們在 GridView 中僅顯示價格小於特定閾值的產品。 先在 ParameterizedQueries.aspx
頁面上新增一個文字輸入框,以從使用者收集此閾值。 將 TextBox 的 ID
屬性設為 MaxPrice
。 新增按鈕 Web 控制項並將其 Text
屬性設為「顯示相符產品」。
接下來,將 GridView 拖曳到頁面上,並從其智慧標籤中選擇建立一個名為 ProductsFilteredByPriceDataSource
的新 SqlDataSource。 從「設定資料來源」精靈中,前往「指定自訂 SQL 陳述式或預存程序」畫面 (請參閱圖 4) 並輸入下列查詢:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
輸入查詢 (手動或透過查詢產生器) 後,按一下「下一步」。
圖 4:只傳回那些小於或等於參數值的產品 (點擊查看完整圖片)
由於查詢包含參數,精靈中的下一個畫面會提示我們輸入參數值的來源。 從參數來源下拉式清單中選擇「控制」,並從 ControlID 下拉式清單中選擇 MaxPrice
(TextBox 控制項的 ID
值)。 您也可以輸入可選的預設值,以便在使用者未在 MaxPrice
文字輸入框中輸入任何文字的情況下使用。 暫時不要輸入預設值。
圖 5:MaxPrice
TextBox 的 Text
屬性作為參數來源 (點擊查看完整圖片)
按一下「下一步」,然後按一下「完成」,以完成「設定資料來源」精靈。 GridView、TextBox、Button 和 SqlDataSource 的宣告式標記如下:
Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
HtmlEncode="False" DataFormatString="{0:c}"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT ProductName, UnitPrice
FROM Products WHERE UnitPrice <= @MaximumPrice">
<SelectParameters>
<asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
請注意,SqlDataSource 的 <SelectParameters>
區段中的參數是 ControlParameter
,其中包括 ControlID
和 PropertyName
等附加屬性。 當叫用 SqlDataSource 的 Select()
方法時,ControlParameter
會從指定的 Web 控制項屬性中取得值並將其指派給 SelectCommand
中的對應參數。 在此範例中,MaxPrice
的 Text 屬性用作 @MaxPrice
參數值。
花一點時間透過瀏覽器查看此頁面。 第一次造訪頁面時或每當 MaxPrice
TextBox 缺少值時,GridView 中不會顯示任何記錄。
圖 6:MaxPrice
文字輸入框為空時不顯示任何記錄 (點擊查看完整圖片)
未顯示產品的原因是,預設情況下,參數值的空字串會轉換為資料庫 NULL
值。 由於比較 [UnitPrice] <= NULL
一律評估為 False,因此不傳回任何結果。
在文字輸入框中輸入一個值,例如 5.00,然後按一下「顯示符合產品」按鈕。 回傳時,SqlDataSource 通知 GridView 它的參數來源之一已更改。 因此,GridView 會重新繫結到 SqlDataSource,顯示那些小於或等於 $5.00 的產品。
圖 7:顯示小於或等於 5.00 美元的產品 (點擊查看完整圖片)
一開始顯示所有產品
我們可能會希望顯示所有產品,而不是在頁面首次載入時不顯示任何產品。 當 MaxPrice
TextBox 為空時,列出所有產品的一種方法是將參數的預設值設為某個非常高的值,例如 1000000,因為 Northwind Traders 不太可能擁有單價超過 1,000,000 美元的庫存。 然而,這種方法不夠泛用,在其他情況下可能無法奏效。
在先前的教學課程 - 宣告式參數和使用 DropDownList 進行主/詳細資訊篩選中,我們也遇到過類似的問題。 我們當時的解決方案是將這個邏輯放在商務邏輯層中。 具體來說,BLL 會檢查傳入值,如果它是 NULL
或某個保留值,則呼叫將路由到傳回所有記錄的 DAL 方法。 如果傳入值是正常篩選值,則會呼叫 DAL 方法,該方法執行 SQL 陳述式,該陳述式使用參數化 WHERE
子句和提供的值。
不幸的是,我們在使用 SqlDataSource 時繞過了該架構。 相反,我們需要自訂 SQL 陳述式,以便在 @MaximumPrice
參數為 NULL
或某個保留值時,智慧抓取所有記錄。 對於本練習,如果 @MaximumPrice
參數等於 -1.0
,則會傳回所有記錄 (-1.0
會作為保留值,因為沒有產品可以具有負 UnitPrice
值)。 為了實現這一點,我們可以使用以下 SQL 陳述式:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
如果 @MaximumPrice
參數等於 -1.0
,則 WHERE
子句會傳回所有記錄。 如果參數值不為 -1.0
,則只會傳回 UnitPrice
小於或等於 @MaximumPrice
參數值的產品。 透過將 @MaximumPrice
參數的預設值設為 -1.0
,在首頁載入時 (或每當 MaxPrice
文字輸入框為空時),@MaximumPrice
將具有 -1.0
值,並顯示所有產品。
圖 8:現在,當 MaxPrice
文字輸入框為空時,將顯示所有產品 (點擊查看完整圖片)
這種方法有幾個注意事項需要注意。 首先,認識到參數的資料類型是根據其在 SQL 查詢中的用法推斷的。 如果將 WHERE
子句從 @MaximumPrice = -1.0
變更為 @MaximumPrice = -1
,則執行時會將參數視為整數。 如果您隨後嘗試將 MaxPrice
TextBox 指派給十進位值 (例如 5.00),則會發生錯誤,因為它無法將 5.00 轉換為整數。 要解決此問題,請確保在 WHERE
子句中使用 @MaximumPrice = -1.0
,或者更好的是,將 ControlParameter
物件的 Type
屬性設為 Decimal。
其次,透過在 WHERE
子句中加入 OR @MaximumPrice = -1.0
,查詢引擎無法在 UnitPrice
上使用索引 (假設其存在),從而導致資料表掃描。 如果 Products
表中的記錄很多,這可能會影響效能。 更好的方法是將此邏輯移至預存程序,其中 IF
陳述式將在需要傳回所有記錄時,從不帶 WHERE
子句的 Products
表執行 SELECT
查詢,或在其 WHERE
子句僅包含 UnitPrice
標準時,執行該查詢,因此可以使用索引。
步驟 3:建立和使用參數化預存程序
預存程序可以包括一組輸入參數,然後可以在預存程序中定義的 SQL 陳述式中使用這些參數。 將 SqlDataSource 設定為使用接受輸入參數的預存程序時,可以使用與臨機操作 SQL 陳述式相同的技術來指定這些參數值。
為了說明如何使用 SqlDataSource 中的預存程序,讓我們在 Northwind 資料庫中建立一個名為 GetProductsByCategory
的新預存程序,該程序接受名為 @CategoryID
的參數,並傳回 CategoryID
列與 @CategoryID
相符的產品的所有列。 若要建立預存程序,請前往「伺服器總管」,並深入查看 NORTHWND.MDF
資料庫。 (如果您沒有看到「伺服器總管」,請前往「檢視」功能表,並選擇「伺服器總管」選項將其開啟。)
在 NORTHWND.MDF
資料庫中,以滑鼠右鍵按一下「預存程序」資料夾,選擇「新增預存程序」,然後輸入以下語法:
CREATE PROCEDURE dbo.GetProductsByCategory
(
@CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID
按一下「儲存」圖示 (或 Ctrl+S) 儲存預存程序。 您可以透過在「預存程序」資料夾中,以滑鼠右鍵按一下該預存程序,然後選擇「執行」來測試該預存程序。 這將提示您輸入預存程序的參數 (在本例中為 @CategoryID
),然後結果將顯示在「輸出」視窗中。
圖 9:@CategoryID
為 1 時執行的 GetProductsByCategory
預存程序 (點擊查看完整圖片)
讓我們使用此預存程序在 GridView 中顯示 Beverages 類別中的所有產品。 將新的 GridView 新增至頁面,並將其繫結至名為 BeverageProductsDataSource
的新 SqlDataSource。 繼續前往指定自訂 SQL 陳述式或預存程序畫面,選擇「預存程序」選項按鈕,然後從下拉式清單中選擇 GetProductsByCategory
預存程序。
圖 10:從下拉式清單中選擇 GetProductsByCategory
預存程序 (點擊查看完整圖片)
由於預存程序接受輸入參數 (@CategoryID
),因此按一下「下一步」會提示我們指定該參數值的來源。 飲料 CategoryID
為 1,因此將「參數來源」下拉式清單保留為「無」,並在「預設值」文字輸入框中輸入 1。
圖 11:使用硬式編碼值 1 傳回飲料類別中的產品 (點擊查看完整圖片)
如下列宣告式標記所示,使用預存程序時,SqlDataSource 的 SelectCommand
屬性設定為預存程序的名稱,SelectCommandType
屬性設為 StoredProcedure
,表示 SelectCommand
是預存程序的名稱,而非臨機操作 SQL 陳述式。
<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
在瀏覽器中測試該頁面。 儘管顯示了所有產品欄位,但僅顯示屬於「飲料」類別的那些產品,因為 GetProductsByCategory
預存程序傳回了 Products
表中的所有欄位。 當然,我們可以從 GridView 的「編輯列」對話方塊限製或自訂 GridView 中顯示的欄位。
圖 12:所有飲料均顯示 (點擊查看完整圖片)
步驟 4:以程式設計方式叫用 SqlDataSource 的 Select() 陳述式
到目前為止,我們在上一篇教學課程和本教學課程中看到的範例,都將 SqlDataSource 控制項直接繫結到 GridView。 然而,SqlDataSource 控制項的資料可以透過程式設計方式在程式碼中存取和列舉。 當您需要查詢資料來檢查資料但不需要顯示它時,這特別有用。 您可以讓 SqlDataSource 處理這些單調的程式碼,而不必編寫所有樣板 ADO.NET 程式碼來連接到資料庫、指定命令並擷取結果。
為了說明以程式設計方式使用 SqlDataSource 資料,假設您的老闆向您提出了建立網頁的需求,該網頁要顯示隨機選擇的類別及其關聯產品的名稱。 也就是說,當使用者造訪這個頁面時,我們要從 Categories
表格中隨機選擇一個類別,顯示類別名稱,然後列出屬於該類別的產品。
為了實現這一點,我們需要兩個 SqlDataSource 控制項,一個用於從 Categories
表中抓取隨機類別,另一個用於獲取該類別的產品。 在此步驟中,我們將建立檢索隨機類別記錄的 SqlDataSource;步驟 5 著重在建立檢索類別產品的 SqlDataSource。
首先將 SqlDataSource 新增到 ParameterizedQueries.aspx
,並將其 ID
設為 RandomCategoryDataSource
。 設定它以便它使用以下 SQL 查詢:
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID()
會傳回隨機順序排序的記錄 (請參閱「使用 NEWID()
對記錄進行隨機排序」)。 SELECT TOP 1
會傳回結果集中的第一筆記錄。 總而言之,此查詢會傳回來自單一隨機選擇的類別的 CategoryID
和 CategoryName
列值。
若要顯示類別的 CategoryName
值,請將 Label Web 控制項新增至頁面,將其 ID
屬性設為 CategoryNameLabel
,然後清除其 Text
屬性。 要以程式設計方式從 SqlDataSource 控制項檢索資料,我們需要叫用其 Select()
方法。 Select()
方法需要一個類型為 DataSourceSelectArguments
的輸入參數,該參數指定在傳回資料之前應如何傳遞資料。 這可以包括有關對資料進行排序和篩選的指令,並由資料 Web 控制項在對來自 SqlDataSource 控制項的資料進行排序或分頁時使用。 但對於我們的範例,我們不需要在傳回資料之前修改資料,因此會傳入 DataSourceSelectArguments.Empty
物件。
Select()
方法會傳回實作 IEnumerable
的物件。 傳回的精確類型取決於 SqlDataSource 控制項的 DataSourceMode
屬性值。 如上一個教學課程所討論的,該屬性可以設定為 DataSet
或 DataReader
的值。 如果設定為 DataSet
,則 Select()
方法會傳回 DataView 物件;如果設定為 DataReader
,則傳回一個實作 IDataReader
的物件。 由於 RandomCategoryDataSource
SqlDataSource 的 DataSourceMode
屬性設定為 DataSet
(預設值),因此我們將使用 DataView 物件。
以下程式碼說明如何從 RandomCategoryDataSource
SqlDataSource 作為 DataView 擷取記錄,以及如何從第一個 DataView 行讀取 CategoryName
列值:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
' Get the data from the SqlDataSource as a DataView
Dim randomCategoryView As DataView = CType _
(RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty), DataView)
If randomCategoryView.Count > 0 Then
' Assign the CategoryName value to the Label
CategoryNameLabel.Text = String.Format( _
"Here are Products in the {0} Category...", _
randomCategoryView(0)("CategoryName").ToString())
End If
End Sub
randomCategoryView(0)
會傳回 DataView 中的第一個 DataRowView
。 randomCategoryView(0)("CategoryName")
會傳回第一行中 CategoryName
列的值。 請注意,DataView 是鬆散類型的。 要參考特定的列值,我們需要將列名稱作為字串傳遞 (在本例中為 CategoryName)。 圖 13 顯示了查看頁面時,CategoryNameLabel
中顯示的訊息。 當然,顯示的實際類別名稱是由 RandomCategoryDataSource
SqlDataSource 在每次造訪頁面 (包括回傳) 時隨機選擇的。
圖 13:顯示隨機選擇的類別名稱 (點擊查看完整圖片)
注意
如果 SqlDataSource 控制項的 DataSourceMode
屬性已設為 DataReader
,則 Select()
方法的傳回值需要轉換為 IDataReader
。 要從第一行讀取 CategoryName
列值,我們使用以下程式碼:
If randomCategoryReader.Read() Then
Dim categoryName as String = randomCategoryReader("CategoryName').ToString()
...
End If
透過 SqlDataSource 隨機選擇一個類別,我們就可以新增列出該類別產品的 GridView。
注意
我們可以將 FormView 或 DetailsView 新增至頁面,並將其繫結到 SqlDataSource,而不是使用 Label Web 控制項來顯示類別名稱。 然而,使用 Label 使我們能夠探索如何以程式設計方式呼叫 SqlDataSource 的 Select()
陳述式,並在程式碼中使用其結果資料。
步驟 5:以程式設計方式指派參數值
到目前為止,我們在本教學課程中看到的所有範例,都使用了硬式編碼參數值或取自預先定義參數來源 (查詢字串值、頁面上的 Web 控制項等) 的參數值。 但是,SqlDataSource 控制項的參數也可以透過程式設定。 為了完成我們目前的範例,我們需要一個傳回屬於指定類別的所有產品的 SqlDataSource。 此SqlDataSource 將有一個 CategoryID
參數,其值需要根據 Page_Load
事件處理常式中 RandomCategoryDataSource
SqlDataSource 傳回的 CategoryID
列值進行設定。
首先將 GridView 新增至頁面,並將其繫結到名為 ProductsByCategoryDataSource
的新 SqlDataSource。 就像我們在步驟 3 中所做的那樣,設定 SqlDataSource,以便它叫用 GetProductsByCategory
預存程序。 將「參數來源」下拉式清單設為「無」,但不要輸入預設值,因為我們將以程式設計方式設定此預設值。
圖 14:不指定參數來源或預設值 (點擊查看完整圖片)
完成 SqlDataSource 精靈後,產生的宣告式標記應該會像這樣:
<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
我們可以在 Page_Load
事件處理常式中,以程式方式指派 CategoryID
參數的 DefaultValue
:
' Assign the ProductsByCategoryDataSource's
' CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters("CategoryID").DefaultValue = _
randomCategoryView(0)("CategoryID").ToString()
新增此內容後,該頁面將包含一個 GridView,用於顯示與隨機選擇的類別關聯的產品。
圖 15:不指定參數來源或預設值 (點擊查看完整圖片)
摘要
SqlDataSource 使頁面開發人員能夠定義參數化查詢,其參數值可以進行硬式編碼、從預先定義的參數來源中提取,或以程式設計方式指派。 在本教學課程中,我們知道了如何從「設定資料來源」精靈為臨機操作 SQL 查詢和預存程序建立參數化查詢。 我們也探討了使用硬式編碼參數來源、Web 控制項作為參數來源,以及以程式設計方式指定參數值。
與 ObjectDataSource 一樣,SqlDataSource 也提供修改其基礎資料的功能。 在下一個教學課程中,我們將了解如何使用 SqlDataSource 定義 INSERT
、UPDATE
和 DELETE
陳述式。 新增這些陳述式後,我們可以利用 GridView、DetailsView 和 FormView 控制項固有的內建插入、編輯和刪除功能。
祝您程式設計愉快!
關於作者
Scott Mitchell,七本 ASP/ASP.NET 書籍的作者和 4GuysFromRolla.com 創始人,自 1998 年以來便開始使用 Microsoft Web 技術。 Scott 擔任獨立顧問、講師和作家。 他的新書是 Sams Teach Yourself ASP.NET 2.0 in 24 Hours。 您可以透過 mitchell@4GuysFromRolla.com 或他的部落格 (可以在 http://ScottOnWriting.NET 找到) 與他聯繫。
特別感謝
本教學課程系列已經過許多熱心的檢閱者檢閱。 本教學課程的主要審閱者是 Scott Clyde、Randell Schmidt 和 Ken Pespisa。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果有,請發信到 mitchell@4GuysFromRolla.com 。