天天看點

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

這篇文章将建立一列包含checkbox控件的datagrid,這個控件允許使用者對明細浏覽進行多列選擇。如果沒有恢複對于動态sql獲得該功能的一種方法,那麼必須使用in操作。

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

在下面顯示了我們用來建立表單的aspx。注意:如何使用templatecolumn和checkbox控件增加datagrid列。我們也使用datagrid的datakeyfield屬性來告訴對象,在資料庫記錄的哪一個字段将會包含第一行的關鍵字标示符。 

<formid="form1"method="post"runat="server">

<asp:datagridid="datagrid1"runat="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:buttonid="orders"runat="server"text="vieworders"></asp:button>

<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();