共用方式為


使用參數和 SqlDataSource 控制項

更新:2007 年 11 月

SQL 陳述式和預存程序通常包含會在執行階段進行評估的參數。使用參數撰寫的 SQL 陳述式稱為參數型 SQL 陳述式。

當使用 SqlDataSource 控制項時,您可以指定使用參數的 SQL 查詢和陳述式。這可以根據在執行階段評估的值讀取和撰寫資料庫資訊,讓資料繫結案例更有彈性。您可以從各種來源取得參數值,包括 ASP.NET 應用程式變數、使用者識別和使用者選取的值。您可以使用參數提供資料擷取的搜尋準則、提供資料存放區中要插入、更新或刪除的值,以及提供排序、分頁和篩選的值。

使用參數

SqlDataSource 控制項就像所有的資料來源控制項,可以在執行階段接受輸入參數,並且在參數集合中加以管理。每個資料作業都有相關的參數集合。您可以在選取作業時使用 SelectParameters 集合,在更新作業時使用 UpdateParameters 集合等等。

您可以為每個參數指定名稱、類型、方向和預設值。從特定物件 (例如控制項、工作階段變數或使用者設定檔) 取得值的參數需要設定其他屬性。例如,ControlParameter 需要設定 ControlID 以識別取得參數值的控制項,並且設定 PropertyName 屬性指定包含參數值的屬性。如需詳細資訊,請參閱使用含有資料來源控制項的參數

SqlDataSource 控制項也會根據支援自動更新、插入和刪除作業的資料繫結控制項 (例如 GridViewFormView 控制項) 所傳遞的值自動建立參數。如需詳細資訊,請參閱資料來源控制項如何建立資料繫結欄位的參數

指定命令參數

當您使用 SqlDataSource 控制項時,可以將控制項的命令屬性設定為參數型 SQL 陳述式或預存程序名稱。如果您指定命令為一預存程序,就必須將命令的類型指定為 StoredProcedure

參數名稱

SqlDataSource 控制項會將 ParameterPrefix 屬性的值加入所有參數名稱的開頭 (預設前置詞是 "@")。

如果是 GridView 之類的資料繫結控制項繫結至 SqlDataSource 控制項,在更新或刪除作業期間,資料繫結控制項會同時將目前和原始的記錄值傳遞至 SqlDataSource 控制項。目前的值會在 Values 字典中傳遞。原始值會在 Keys 或 OldValues 字典中傳遞。這些字典的內容,會附加到指定資料作業之基礎 DbCommand 物件的 Parameters 集合。

SqlDataSource 控制項的 SQL 命令中,可以使用命名慣例讓參數替代符號 (Placeholder) 符合傳遞至命令中的舊值。您可以藉由設定 SqlDataSource 控制項的 OldValuesParameterFormatString 屬性,建立替代符號名稱的格式。將 OldValuesParameterFormatString 屬性設定為包含 "{0}" 當做欄位名稱替代符號的字串。例如,如果您將 OldValuesParameterFormatString 屬性設定為 "old_{0}",原始實值參數的名稱將解析為使用 "@old_" 當做前置字元的欄位名稱。請考慮牽涉名為 LastModifiedDate 的欄位更新作業。欄位目前的值會在 Values 字典中傳遞,並且欄位的原始值會在 OldValues 字典中傳遞。還會建立名為 @LastModifiedDate 的參數傳遞目前的值,並且建立名為 @old\_LastModifiedDate 的參數傳遞原始值。然後可以在 SQL 陳述式中同時包含兩種參數,區分欄位目前的值和原始值,如同下列程式碼範例所示:

UPDATE Table1 SET LastModifiedDate = @LastModifiedDate
  WHERE Key = @Key AND LastModifiedDate = @old_LastModifiedDate

在執行開放式並行存取 (Optimistic Concurrency) 檢查或使用能夠修改主索引鍵的資料來源時,必須要能夠在命令中分隔目前的值和原始值。

如需資料繫結控制項所傳遞字典的詳細資訊,請參閱資料來源控制項如何建立資料繫結欄位的參數

搭配 SqlClient 提供者使用參數

根據預設,SqlDataSource 控制項會使用 System.Data.SqlClient 資料提供者將 SQL Server 當做資料來源運用。System.Data.SqlClient 提供者支援將具名參數當做替代符號,如同下列程式碼範例所示:

SELECT * FROM Employees WHERE LastName = @LastName 
  AND FirstName = @FirstName

使用具名參數時,在命令參數集合中指定參數的順序並不重要。然而,您必須確認在 SQL 命令中使用的參數名稱,能夠對應至相關集合中的參數名稱。

下列程式碼範例示範如何在使用 System.Data.SqlClient 提供者之 SqlDataSource 控制項的 SQL 命令中使用具名參數。

<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource" 
  SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID"

  InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName); 
                 SELECT @EmpID = SCOPE_IDENTITY()"
  UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName 
                   WHERE EmployeeID=@EmployeeID"
  DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"

  ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
  OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
  RunAt="server">

  <SelectParameters>
    <asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
  </SelectParameters>

  <InsertParameters>
    <asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
  </InsertParameters>

</asp:sqlDataSource>
<asp:sqlDataSource ID="EmployeeDetailsSqlDataSource" 
  SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees WHERE EmployeeID = @EmpID"

  InsertCommand="INSERT INTO Employees(LastName, FirstName) VALUES (@LastName, @FirstName); 
                 SELECT @EmpID = SCOPE_IDENTITY()"
  UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName 
                   WHERE EmployeeID=@EmployeeID"
  DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"

  ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
  OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
  RunAt="server">

  <SelectParameters>
    <asp:Parameter Name="EmpID" Type="Int32" DefaultValue="0" />
  </SelectParameters>

  <InsertParameters>
    <asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
  </InsertParameters>

</asp:sqlDataSource>

搭配 OleDb 和 Odbc 提供者使用參數

如果您連接至 OLE DB 或 ODBC 資料來源,可以設定 SqlDataSource 控制項搭配資料來源,以各自使用 System.Data.OleDbSystem.Data.Odbc 提供者。System.Data.OleDbSystem.Data.Odbc 提供者只支援由 "?" 字元所識別的位置參數,如同下列程式碼範例所示:

SELECT * FROM Employees WHERE LastName = ? AND FirstName = ?

當您搭配參數型 SQL 陳述式使用 System.Data.OleDbSystem.Data.Odbc 提供者時,指定參數替代符號的順序,必須符合相關參數集合中的參數順序。您可以在相關資料作業的集合中明確指定參數順序以加以控制,例如相關 UpdateCommandUpdateParameters 集合。當您明確建立參數的集合,而這個參數是從資料繫結控制項的傳遞值而自動建立時,明確建立的參數會覆寫自動產生的任何參數。這樣一來可以確認會使用您想要的順序傳遞參數。如果您呼叫會傳回值的預存程序,必須指定具有 ReturnValueDirection 值之參數,做為命令參數集合中的第一個參數。

注意事項:

根據預設,依據資料繫結控制項繫結欄位的參數,會使用下列順序從參數字典中加入命令:Values、Keys、OldValues。刪除作業只會使用 Keys 字典。插入作業只會使用 Values 字典。如需資料繫結控制項所傳遞字典的詳細資訊,請參閱資料來源控制項如何建立資料繫結欄位的參數

下列程式碼範例示範如何指定使用 System.Data.OleDb 提供者之 SqlDataSource 控制項的參數。參數會明確指定以確認在集合中的參數順序,符合 SQL 陳述式中的替代符號順序。

<Fields>                  
  <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>                    
  <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>
  <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>                    
  <asp:TemplateField HeaderText="Birth Date">
    <ItemTemplate> 
      <asp:Label ID="BirthDateLabel" Runat="Server" 
                 Text='<%# Eval("BirthDate", "{0:d}") %>' />
    </ItemTemplate>
    <InsertItemTemplate>
      <asp:Calendar ID="InsertBirthDateCalendar" Runat="Server"
                    SelectedDate='<%# Bind("BirthDate") %>' />
    </InsertItemTemplate>
    <EditItemTemplate>
      <asp:Calendar ID="EditBirthDateCalendar" Runat="Server"
                    VisibleDate='<%# Eval("BirthDate") %>'
                    SelectedDate='<%# Bind("BirthDate") %>' />
    </EditItemTemplate>
  </asp:TemplateField>                    
</Fields> 
<Fields>                  
  <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>                    
  <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>
  <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>                    
  <asp:TemplateField HeaderText="Birth Date">
    <ItemTemplate> 
      <asp:Label ID="BirthDateLabel" Runat="Server" 
                 Text='<%# Eval("BirthDate", "{0:d}") %>' />
    </ItemTemplate>
    <InsertItemTemplate>
      <asp:Calendar ID="InsertBirthDateCalendar" Runat="Server"
                    SelectedDate='<%# Bind("BirthDate") %>' />
    </InsertItemTemplate>
    <EditItemTemplate>
      <asp:Calendar ID="EditBirthDateCalendar" Runat="Server"
                    VisibleDate='<%# Eval("BirthDate") %>'
                    SelectedDate='<%# Bind("BirthDate") %>' />
    </EditItemTemplate>
  </asp:TemplateField>                    
</Fields> 

請參閱

概念

使用 SqlDataSource 控制項選取資料

使用 SqlDataSource 控制項修改資料

參考

SqlDataSource

AccessDataSource