使用以 SqlDataSource 進行的參數化查詢 (C#)

作者:Scott Mitchell

下載 PDF

在本教學課程中,我們會繼續查看 SqlDataSource 控件,並瞭解如何定義參數化查詢。 參數可以宣告方式和程序設計方式指定,而且可以從許多位置提取,例如querystring、會話狀態、其他控件等等。

簡介

在上一個教學課程中,我們已瞭解如何使用 SqlDataSource 控件直接從資料庫擷取數據。 使用 [設定數據源精靈],我們可以選擇資料庫,然後:挑選要從數據表或檢視傳回的數據行;輸入自定義 SQL 語句;或使用預存程式。 無論是從數據表或檢視選取數據行或輸入自定義 SQL 語句,SqlDataSource 控件的 SelectCommand 屬性都會獲指派產生的臨機操作 SQL SELECT 語句,而且這是在以程式設計方式或自動從數據 Web 控件) 叫用 SqlDataSource s 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 支援語句和 INSERTUPDATEDELETE 語句的參數化查詢SELECT。 此外,參數值也可以從各種來源自動提取查詢字串、會話狀態、頁面上的控件等等,也可以以程序設計方式指派。 在本教學課程中,我們將瞭解如何定義參數化查詢,以及如何以宣告方式和以程序設計方式指定參數值。

注意

在上一個教學課程中,我們將 ObjectDataSource 與 SqlDataSource 比較,這是我們在前 46 個教學課程中所選擇的工具,並指出其概念相似性。 這些相似性也會延伸至參數。 對應至商業規則層中方法之輸入參數的 ObjectDataSource 參數。 使用 SqlDataSource 時,參數會直接定義在 SQL 查詢內。 這兩個控件都有其 Select()Insert()Update()Delete() 方法的參數集合,而且兩者都可以從預先定義的來源填入這些參數值, (查詢字串值、會話變數等等) 或以程序設計方式指派。

建立參數型查詢

SqlDataSource 控件的 [設定數據源精靈] 提供三個路徑,用來定義要執行的命令來擷取資料庫記錄:

  • 從現有的數據表或檢視中挑選數據行,
  • 輸入自定義 SQL 語句,或
  • 選擇預存程式

從現有的數據表或檢視中挑選數據行時,子句的參數 WHERE 必須透過 [加入 WHERE 子句] 對話框來指定。 不過,建立自定義 SQL 語句時,您可以使用 直接在 子句中輸入參數 WHERE (@parameterName 來表示每個參數) 。 預存程式是由一或多個 SQL 語句所組成,而且這些語句可以參數化。 不過,SQL 語句中使用的參數必須當做輸入參數傳入預存程式。

由於建立參數化查詢取決於 SqlDataSource 的 SelectCommand 指定方式,讓我們看看這三種方法。 若要開始使用,請開啟ParameterizedQueries.aspx資料夾中的頁面SqlDataSource,將 SqlDataSource 控制件從 [工具箱] 拖曳至 Designer,並將其設定IDProducts25BucksAndUnderDataSource。 接下來,按兩下控件智慧標記中的 [設定資料源] 連結。 選取要使用的資料庫 (NORTHWINDConnectionString) ,然後按 [下一步]。

步驟 1:從數據表或檢視挑選數據行時新增 WHERE 子句

使用 SqlDataSource 控件從資料庫選取要傳回的數據時,[設定數據源精靈] 可讓我們只挑選從現有數據表或檢視傳回的數據行, (請參閱圖 1) 。 這麼做會自動建立 SQL 語句,也就是叫用 SqlDataSource SELECT s Select() 方法時傳送至資料庫的內容。 如同我們在上一個教學課程中所做的一樣,請從下拉式清單中選取 [Products] 數據表,然後檢查 ProductIDProductName和 數據 UnitPrice 行。

挑選要從數據表或檢視傳回的數據行

圖 1:挑選要從數據表或檢視表傳回的數據行 (按兩下即可檢視大小完整的影像)

WHERE若要在語句中包含 SELECT 子句,請按下WHERE按鈕,其會顯示 [新增WHERE子句] 對話框, (請參閱圖 2) 。 若要新增參數來限制查詢傳 SELECT 回的結果,請先選擇數據行來篩選數據。 接下來,選擇要用於篩選 (=、、 <= <、、 >等) 的運算符。 最後,選擇參數值的來源,例如從 querystring 或會話狀態。 設定參數之後,按兩下 [新增] 按鈕以將它包含在查詢中 SELECT

在此範例中,讓我們只傳回值小於或等於 $25.00 的結果 UnitPrice 。 因此,從 [資料行] 下拉式清單中挑選 ,並從 <[運算符] 下拉式清單中挑選 UnitPrice = 。 使用硬式編碼參數值時, (例如 $25.00) ,或是以程序設計方式指定參數值時,請從 [來源] 下拉式清單中選取 [無]。 接下來,在 [值] 文本框中輸入硬式編碼參數值 25.00,然後按兩下 [新增] 按鈕來完成此程式。

限制從 [新增 WHERE 子句] 對話框傳回的結果

圖 2:限制從 [新增 WHERE 子句] 對話框傳回的結果, (按兩下即可檢視大小完整的影像)

新增 參數之後,按兩下 [確定] 傳回 [設定數據源精靈]。 精 SELECT 靈底部的 語句現在應該包含 WHERE 名為 的 參數 @UnitPrice的 子句:

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

注意

如果您在 子句中從 [新增WHERE子句] 對話框指定WHERE多個條件,精靈就會將它們與 AND 運算符聯結。 如果您需要 OR 在 子句中包含 WHERE (,例如 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 s Select() 方法時, UnitPrice 參數值 (25.00) 會套用至 @UnitPrice 中的 SelectCommand 參數,再傳送至資料庫。 淨結果是只有小於或等於 $25.00 的產品會從 Products 數據表傳回。 若要確認這一點,請將 GridView 新增至頁面、將它系結至此數據源,然後透過瀏覽器檢視頁面。 您應該只會看到列出小於或等於 $25.00 的產品,如圖 3 確認。

只會顯示小於或等於 $25.00 的產品

圖 3:只有小於或等於 $25.00 的產品會顯示 (按兩下即可檢視大小完整的影像)

步驟 2:將參數新增至自訂 SQL 語句

新增自訂 SQL 語句時,您可以明確輸入 WHERE 子句,或在查詢產生器的 Filter 單元格中指定值。 為了示範這點,讓我們在 GridView 中只顯示價格小於特定臨界值的產品。 首先,將 TextBox 新增至 ParameterizedQueries.aspx 頁面,以收集使用者的此臨界值。 將 TextBox 的 ID 屬性設定為 MaxPrice。 新增 Button Web 控制件,並將其屬性設定 Text 為 [顯示相符產品]。

接下來,將 GridView 拖曳到頁面,並從其智慧標記中選擇建立名為 ProductsFilteredByPriceDataSource的新 SqlDataSource。 從 [設定數據源精靈] 中,繼續進行 [指定自定義 SQL 語句或預存程式] 畫面, (請參閱圖 4) 並輸入下列查詢:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice

在手動輸入查詢 (或透過查詢產生器) 之後,請按 [下一步]。

只傳回小於或等於參數值的這些產品

圖 4:僅傳回小於或等於參數值 (按兩下即可檢視完整大小的影像)

由於查詢包含參數,精靈中的下一個畫面會提示我們輸入參數值的來源。 從 [參數來源] 下拉式清單中選擇 [控件],然後 MaxPrice 從 ControlID 下拉式清單中) (TextBox 控制件 ID 的值。 您也可以輸入選擇性的預設值,以在使用者未在 TextBox 中 MaxPrice 輸入任何文字的情況下使用。 目前請勿輸入預設值。

MaxPrice TextBox 的 Text 屬性會當做參數來源使用

圖 5MaxPrice TextBox s 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 s <SelectParameters> 區段中的參數是 ControlParameter,其中包含 和 等其他ControlIDPropertyName屬性。 叫用 SqlDataSource s Select() 方法時,會 ControlParameter 從指定的 Web 控件屬性擷取值,並將它指派給 中的 SelectCommand對應參數。 在此範例中 MaxPrice ,會使用 Text 屬性做為 @MaxPrice 參數值。

請花一分鐘的時間透過瀏覽器檢視此頁面。 第一次瀏覽頁面時,或 MaxPrice 每當 TextBox 缺少值時,GridView 中就不會顯示任何記錄。

當 MaxPrice TextBox 是空的時,不會顯示任何記錄

圖 6:當 MaxPrice TextBox 是空白 (按兩下即可檢視完整大小的影像 時,不會顯示任何記錄)

沒有顯示產品的原因是,根據預設,參數值的空字串會轉換成資料庫 NULL 值。 由於的 [UnitPrice] <= NULL 比較一律會評估為 False,因此不會傳回任何結果。

在文字框中輸入值,例如 5.00,然後按兩下 [顯示相符產品] 按鈕。 在回傳時,SqlDataSource 會通知 GridView 其其中一個參數來源已變更。 因此,GridView 會重新系結至 SqlDataSource,顯示小於或等於 $5.00 的產品。

顯示小於或等於 $5.00 的產品

圖 7:[小於或等於 $5.00 的產品] 會顯示 (按兩下即可檢視大小完整的影像)

一開始顯示所有產品

我們可能不會在頁面第一次載入時顯示任何產品,而是想要顯示 所有 產品。 每當 MaxPrice TextBox 是空的時列出所有產品的方法之一,就是將參數的預設值設定為一些不定期的高值,例如 10000000,因為 Northwind Traders 不太可能會有單價超過 $1,000,000 的庫存。 不過,這種方法是簡短的,在其他情況下可能無法運作。

在先前的教學課程 - 宣告式參數主要/詳細數據篩選使用DropDownList 時,我們遇到類似的問題。 我們的解決方案是在商業規則層中放置此邏輯。 具體而言,BLL 會檢查傳入值,如果它是 NULL 或某些保留值,呼叫就會路由傳送至傳回所有記錄的 DAL 方法。 如果傳入值是一般篩選值,則會呼叫 DAL 方法,該方法會執行使用參數化 WHERE 子句搭配所提供值的 SQL 語句。

不幸的是,我們使用 SqlDataSource 時略過架構。 相反地,我們需要自定義 SQL 語句,以在 參數為 NULL 或某些保留值時@MaximumPrice,以智慧方式擷取所有記錄。 在此練習中,讓我們擁有它,讓參數 @MaximumPrice 等於 -1.0,則 所有 記錄都會傳回 (-1.0 做為保留值,因為沒有任何產品可以有負 UnitPrice 值) 。 若要達成此目的,我們可以使用下列 SQL 語句:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

如果 參數等於 -1.0@MaximumPrice這個WHERE子句會傳回所有記錄。 如果參數值不是 -1.0,則只會傳回小於或等於@MaximumPrice參數值的產品UnitPrice。 藉由將 參數的 @MaximumPrice 預設值設定為 -1.0,在第一頁載入 (,或每當 MaxPrice TextBox 是空的) 時, @MaximumPrice 都會有的值 -1.0 ,而且會顯示所有產品。

現在當 MaxPrice TextBox 是空的時,會顯示所有產品

圖 8:當 TextBox 是空白 (按兩下即可檢視全大小的影像時,MaxPrice會顯示所有產品)

有一些注意事項可注意此方法。 首先,了解參數的數據類型是由 SQL 查詢中的使用量所推斷。 如果您將 WHERE 子句從 @MaximumPrice = -1.0 變更為 @MaximumPrice = -1,運行時間會將 參數視為整數。 如果您接著嘗試將 MaxPrice TextBox 指派給 decimal 值, (例如 5.00 ) ,就會發生錯誤,因為它無法將 5.00 轉換成整數。 若要解決此問題,請確定您在 @MaximumPrice = -1.0 子句中使用 WHERE ,或更妥善地將 ControlParameter 物件 s Type 屬性設定為 Decimal 。

其次,藉由將 加入 OR @MaximumPrice = -1.0WHERE 子句,查詢引擎無法在 (上使用 UnitPrice 索引,假設其中一個存在) ,因而導致數據表掃描。 如果數據表中有 Products 足夠大量的記錄,這可能會影響效能。 更好的方法是將此邏輯移至預存程式,其中IF語句會在傳回所有記錄時從數據表WHERE執行SELECT查詢Products,或是其中一個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,在此實例中) ,結果會在 [輸出] 視窗中顯示。

當使用 <span 類別執行時,GetProductsByCategory 預存程式=@CategoryID 為 1“ />

圖 9GetProductsByCategory@CategoryID 1 個 (按一下執行時執行的預存程式 ,以檢視完整大小的映像)

讓我們使用此預存程式,在 GridView 的 [排序] 類別中顯示所有產品。 將新的 GridView 新增至頁面,並將其系結至名為 BeverageProductsDataSource的新 SqlDataSource。 繼續進行 [指定自定義 SQL 語句或預存程式] 畫面,選取 [預存程式] 單選按鈕,然後從下拉式清單中挑選 GetProductsByCategory 預存程式。

從 Drop-Down 清單中選取 GetProductsByCategory 預存程式

圖 10:從 [Drop-Down 列表] 選取 GetProductsByCategory [預存程式] (按鍵即可檢視大小完整的映射)

由於預存程式接受輸入參數 (@CategoryID) ,請按兩下 [下一步] 會提示我們指定此參數值的來源。 [參數 CategoryID 來源] 下拉式清單保留 [無],然後在 [DefaultValue] 文本框中輸入 1。

使用 Hard-Coded 值為 1 可傳回[商品類別] 中的產品

圖 11:使用 Hard-Coded 值為 1 可傳回 [ (按兩下以檢視大小完整的影像)

如下列宣告式標記所示,使用預存程式時,SqlDataSource s 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 s 編輯數據行] 對話框,限制或自定義 GridView 中顯示的欄位。

所有水殭都會顯示

圖 12:[ 按兩下] 即可檢視全尺寸影像) 顯示所有[ (]

步驟 4:以程序設計方式叫用 SqlDataSource 的 Select () 語句

我們在上一個教學課程中所見的範例,到目前為止本教學課程已將 SqlDataSource 控件直接系結至 GridView。 不過,SqlDataSource 控件的數據可以在程式代碼中以程序設計方式存取和列舉。 當您需要查詢數據以檢查數據,但不需要顯示數據時,這特別有用。 您不必撰寫所有重複使用的程式代碼 ADO.NET 程式代碼來連線到資料庫、指定命令並擷取結果,您可以讓 SqlDataSource 處理這個單調的程式代碼。

為了說明以程序設計方式使用 SqlDataSource 數據,假設您的主管已要求您建立一個網頁,以顯示隨機選取類別的名稱及其相關聯的產品。 也就是說,當使用者瀏覽此頁面時,我們想要從 Categories 數據表隨機選擇類別、顯示類別名稱,然後列出屬於該類別的產品。

為了達成此目的,我們需要兩個 SqlDataSource 控件,一個從數據表擷取隨機類別 Categories ,另一個則是取得類別的產品。 我們將建置 SqlDataSource 來擷取此步驟中的隨機類別記錄;步驟 5 會探討如何製作可擷取類別產品的 SqlDataSource。

首先,將 SqlDataSource 新增至 ParameterizedQueries.aspx ,並將其設定 IDRandomCategoryDataSource。 設定它,使其使用下列 SQL 查詢:

SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()

ORDER BY NEWID() 會傳回以隨機順序排序的記錄, (請參閱 使用 NEWID() 來隨機排序記錄) 。 SELECT TOP 1 會從結果集傳回第一筆記錄。 結合在一起,此查詢會 CategoryID 從單一隨機選取的類別傳回 和 CategoryName 數據行值。

若要顯示類別的值 CategoryName ,請將標籤 Web 控件新增至頁面、將其 ID 屬性設定為 CategoryNameLabel,並清除其 Text 屬性。 若要以程序設計方式從 SqlDataSource 控件擷取數據,我們需要叫用其 Select() 方法。 方法Select()需要類型的DataSourceSelectArguments單一輸入參數,它會指定在傳回之前應該如何訊息數據。 這可以包含排序和篩選數據的指示,並在排序或分頁 SqlDataSource 控制件的數據時由數據 Web 控制項使用。 不過,在我們的範例中,我們不需要在傳回之前修改數據,因此會傳入 DataSourceSelectArguments.Empty 物件。

方法 Select() 會傳回實作 IEnumerable的物件。 傳回的精確型別取決於 SqlDataSource 控件的 DataSourceMode 屬性值。 如上一個教學課程所述,此屬性可以設定為 或DataReader的值DataSet。 如果設定為 DataSet,則 Select() 方法會傳回 DataView 物件;如果設定為 DataReader,則會傳回實作 的物件 IDataReaderRandomCategoryDataSource由於 SqlDataSource 的 DataSourceMode 屬性設定為 DataSet (預設) ,因此我們將使用 DataView 物件。

下列程式代碼說明如何從 RandomCategoryDataSource SqlDataSource 擷取記錄作為 DataView,以及如何從第一個 DataView 數據列讀取 CategoryName 數據行值:

protected void Page_Load(object sender, EventArgs e)
{
    // Get the data from the SqlDataSource as a DataView
    DataView randomCategoryView =
        (DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
    if (randomCategoryView.Count > 0)
    {
        // Assign the CategoryName value to the Label
        CategoryNameLabel.Text =
            string.Format("Here are Products in the {0} Category...",
                randomCategoryView[0]["CategoryName"].ToString());
    }
}

randomCategoryView[0] 會傳回 DataView 中的第一個 DataRowViewrandomCategoryView[0]["CategoryName"] 會傳回這個第一個數據列中數據 CategoryName 行的值。 請注意,DataView 是鬆散類型的。 若要參考特定數據行值,我們需要將數據行的名稱當做字串傳遞 ( CategoryName,在此案例中為) 。 圖 13 顯示檢視頁面時顯示在中的 CategoryNameLabel 訊息。 當然,每個造訪頁面上的 SqlDataSource 會隨機選取 RandomCategoryDataSource 顯示的實際類別名稱, (包括回傳) 。

隨機選取的類別名稱隨即顯示

圖 13:隨機選取的類別名稱會顯示 (按兩下即可檢視大小完整的影像)

注意

如果 SqlDataSource 控制件的 DataSourceMode 屬性已設定為 DataReader,則必須將 方法的 Select() 傳回值轉換成 IDataReader。 若要從第一個數據列讀取資料 CategoryName 行值,我們會使用程式代碼,例如:

if (randomCategoryReader.Read())
{
   string categoryName = randomCategoryReader["CategoryName"].ToString();
   ...
}

透過 SqlDataSource 隨機選取類別,我們就可以新增列出類別產品的 GridView。

注意

我們不需要使用標籤 Web 控件來顯示類別名稱,而是可以將 FormView 或 DetailsView 新增至頁面,並將它系結至 SqlDataSource。 不過,使用 Label 可讓我們探索如何以程式設計方式叫用 SqlDataSource s Select() 語句,並在程式碼中處理其產生的數據。

步驟 5:以程式設計方式指派參數值

本教學課程中到目前為止所見的所有範例都使用硬式編碼參數值,或取自其中一個預先定義參數來源的範例, (查詢字串值、頁面上的 Web 控件,依此類推) 。 不過,您也可以以程式設計方式設定 SqlDataSource 控件的參數。 若要完成目前的範例,我們需要 SqlDataSource,以傳回屬於指定類別的所有產品。 這個 SqlDataSource 會有參數CategoryID,其值必須根據CategoryID事件處理程式中 Page_Load SqlDataSource 傳RandomCategoryDataSource回的數據行值來設定。

首先,將 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>

我們可以在事件處理程式中以程式設計方式指派 DefaultValue 參數的 Page_LoadCategoryID

// 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 定義 INSERTUPDATEDELETE 語句。 新增這些語句之後,我們可以利用 GridView、DetailsView 和 FormView 控件固有的內建插入、編輯和刪除功能。

快樂的程序設計!

關於作者

Scott Mitchell 是七份 ASP/ASP.NET 書籍的作者,以及 1998 年以來與 Microsoft Web 技術合作的 4GuysFromRolla.com 作者。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格來連線到 ,您可以在 找到http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者檢閱。 本教學課程的首席檢閱者是 Scott Clyde、Randell Schmidt 和 Ken Pespisa。 有興趣檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。