閱讀23 返回首頁    go 阿裏雲 go 技術社區[雲棲]


在ASP.NET中使用SQL的IN操作

這篇文章將建立一列包含CheckBox控件的DataGrid,這個控件允許用戶對明細瀏覽進行多列選擇。如果沒有恢複對於動態SQL獲得該功能的一種方法,那麼必須使用IN操作。

在文章的結尾,我們寫了一個SQLServer用戶自定義函數(UDF),為了將一個字符串分解成帶分隔符的子字符串。在這篇文章中,我們能看到這樣一個UDF如何派得上用場。我們將建立一個web表單,在此用戶可以通過選擇checkbox控件而選擇一些在DataGrid中的記錄。對這些被檢查的記錄的明細將會出現在表單中的另一個DataGrid中。這個表單像來如圖所示。

在下麵顯示了我們用來建立表單的ASPX。注意:如何使用TemplateColumn和Checkbox控件增加DataGrid列。我們也使用DataGrid的DataKeyField屬性來告訴對象,在數據庫記錄的哪一個字段將會包含第一行的關鍵字標示符。 

<formmethod="post"runat="server">
<asp:DataGridrunat="server"
 AutoGenerateColumns="False"DataKeyField="EmployeeID">
 <Columns>
<asp:TemplateColumn>
 <ItemTemplate>
<asp:CheckBoxrunat="server"ID="EmployeeCheckBox"/>
 </ItemTemplate>
</asp:TemplateColumn>
 <asp:TemplateColumn>
<ItemTemplate>
 <%#DataBinder.Eval(Container.DataItem,"LastName")%>,
 <%#DataBinder.Eval(Container.DataItem,"FirstName")%>
</ItemTemplate>
 </asp:TemplateColumn>
</Columns>
</asp:DataGrid>

<hr>

<asp:Buttonrunat="server"Text="ViewOrders"></asp:Button>
<hr>
<asp:DataGridID="DataGrid2"Runat="server"AutoGenerateColumns="True"/>
</form>

當表單加載初始化時,需要組裝頂端的DataGrid。代碼使用EnterpriseLibrary來存取SQLSeverNorthwind例子數據庫並且執行“SELECTEmployeeID,FirstName,LastNameFROMEmployees”這一語句。加載事件的代碼如下:

privatevoidPage_Load(objectsender,System.EventArgse)
{
 if(!Page.IsPostBack)
 {
Databasedb=DatabaseFactory.CreateDatabase();
DBCommandWrapperdbCommandWrapper;

using(dbCommandWrapper=db.GetSqlStringCommandWrapper(SELECT_EMPLOYEES))
{
 using(IDataReaderdataReader=db.ExecuteReader(dbCommandWrapper))
 {
DataGrid1.DataSource=dataReader;
DataGrid1.DataBind();
 }
}
 }
}

當用戶單擊“Orders”按鈕時,我們想顯示與數據庫中的那些與Employees相配並與Orders數據相關的第二個數據表格。這樣做的一種方法是建立動態的SQL並且使用所有EmployeeIDs所需的WHERE語句的OR條件。

第二個方法是使用WHERE語句的IN操作。IN操作將會一列表達式進行比較。例如,下列語句返回employee中IDS7和4之間的信息。

SELECTEmployeeID,FirstName,LastNameFROMEmployeesWHEREEmployeeIDIN(7,4)

在觀念上說,我願意使用一個單一字符串參數來查詢所傳遞的IDs,然而,也許作為一個單字符串,不能對IN操作使用一個單一字符串參數。如果那樣,SQL語句會這樣“WHEREEmployeeIN(‘7,4’)”,並且數據庫因為EmployeeID屬於類型int—不屬於varchar類型而返回一個錯誤消息。

不過,我們使用文章中構造的split函數將字符串分離成不同的值。向split函數傳遞字符串‘7,4’,並且我們會得到與值4和7相對應的兩條記錄。選擇employees並且計算它們的定單總數的SQL查詢,將會如下:

SELECTcount(*)ASOrders,E.FirstName,E.LastName

FROMOrdersO

INNERJOINEmployeesEONO.EmployeeID=E.EmployeeID

WHEREE.EmployeeIDIN(SELECTValueFROMfn_Split(@employeeIDs,','))

GROUPBYFirstName,LastName

ORDERBYcount(*)DESC

使用以上查詢所需要的是必須建立和傳遞@employeeIDs參數。這個參數將是用逗號隔開的IDs列表。為了建立該字符串,為了弄明白行是否被用戶選擇,我們需要使用一個循環,這一循環以行數循環次數,並且檢查每一個checkbox控件。如果用戶選擇了行,通過從表的DataKeys屬性中(它被建立在ASPX文件中來指向EmployeeID字段)提取檢驗人,將關鍵字保存在employee中。

privatestringGetCheckedEmployeeIDs()
{
 Stringdelimiter=String.Empty;
 StringBuilderemployeeIDs=newStringBuilder();
 for(inti=0;i<DataGrid1.Items.Count;i++)
 {
CheckBoxcheckbox;
checkbox=DataGrid1.Items[i].FindControl("EmployeeCheckBox")asCheckBox;
if(checkbox!=null&&checkbox.Checked==true)
{
 employeeIDs.Append(delimiter+DataGrid1.DataKeys[i].ToString());
 delimiter=",";
}
 }

 returnemployeeIDs.ToString();
}

以上方法返回一個字符串,像“10,7,20”。對Orders按鈕單擊事件處理器將涉及這樣一個方法,將信息傳遞至SQL以得到employees和orders的列表,並且將其結果綁定在第二個DataGrid對象中。

privatevoidOrders_Click(objectsender,System.EventArgse)
{
 stringemployeeIDs=GetCheckedEmployeeIDs();
 Databasedb=DatabaseFactory.CreateDatabase();
 DBCommandWrapperdbCommandWrapper;

 using(dbCommandWrapper=db.GetSqlStringCommandWrapper(SELECT_ORDERS))
 {
dbCommandWrapper.AddInParameter("@employeeIDs",DbType.String,employeeIDs);
using(IDataReaderdataReader=db.ExecuteReader(dbCommandWrapper))
{
 DataGrid2.DataSource=dataReader;
 DataGrid2.DataBind();
}
 }
}

最後更新:2017-04-02 00:06:36

  上一篇:go 你不知道但很有用的60個生活知識
  下一篇:go ASP.NET Web Page應用深入探討