我有一个从四个表填充的gridview,而select命令(如下所示)功能齐全。我希望能够搜索gridview,并且只显示那些“Status”列值等于下拉列表中所选项目的行。我相信我有正确的选择声明(也在下面列出),但我只希望gridview在按钮点击时显示搜索结果。如何使这个select语句有条件?换句话说,我如何才能使用Search select语句仅在用户点击搜索按钮时使用?
常规选择声明:
SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId"
我的搜索选择语句:
`SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState,
Broker.EntityType, Submission.Coverage, Status.Status FROM Submission WHERE Status = '" + Ddl.SelectedItem.Text + "' INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId
INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId">`
完整的gridview / droplist代码:
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="SqlDataSource2" DataTextField="Status" DataValueField="Status">
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
SelectCommand="SELECT [Status] FROM [Status]"></asp:SqlDataSource>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Search" />
</asp:Panel>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
EmptyDataText="There are no data records to display." AllowPaging="True"
BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px"
CellPadding="3" GridLines="Vertical" HorizontalAlign="Center"
AllowSorting="True" >
<AlternatingRowStyle BackColor="#DCDCDC" />
<Columns>
<asp:BoundField DataField="SubId" HeaderText="Submission Id"
SortExpression="SubId" >
</asp:BoundField>
<asp:BoundField DataField="CustName" HeaderText="Customer"
SortExpression="CustName" />
<asp:BoundField DataField="CustCity" HeaderText="Customer City"
SortExpression="CustCity" />
<asp:BoundField DataField="CustState" HeaderText="Customer State"
SortExpression="CustState" />
<asp:BoundField DataField="BroName" HeaderText="Broker"
SortExpression="BroName" />
<asp:BoundField DataField="BroState" HeaderText="Broker State"
SortExpression="BroState" />
<asp:BoundField DataField="EntityType" HeaderText="Entity Type"
SortExpression="EntityType" />
<asp:BoundField DataField="Coverage"
HeaderText="Coverage" SortExpression="Coverage" />
<asp:BoundField DataField="Status" HeaderText="Status"
SortExpression="Status" />
<asp:HyperLinkField DataNavigateUrlFields="SubId"
DataNavigateUrlFormatString="View.aspx?SubId={0}" Text="View" />
<asp:HyperLinkField DataNavigateUrlFields="SubId"
DataNavigateUrlFormatString="ViewEdit.aspx?SubId={0}" HeaderText="Edit"
Text="Edit" />
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#0000A9" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#000065" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
ProviderName="<%$ ConnectionStrings:ProductInstanceString.ProviderName %>"
SelectCommand="SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId">
</asp:SqlDataSource>
答案 0 :(得分:1)
首先,您肯定希望在SQL中使用参数。您发布的示例很容易受到SQL注入攻击。
其次,您可以通过使用存储过程(也具有许多其他好处)来实现一种类型的查询或另一种查询。在该过程中,您可以检查要传入的状态参数是否为空。如果它为null,则使用常规,如果它不使用搜索语句。
在你的数据库中,你可以创建一个看起来像这样的存储过程(它可能更优雅,但这是一个简单的例子):
CREATE PROCEDURE [dbo].[GetStuffByStatus]
@status varchar(255) = null
AS
BEGIN
IF @status IS NOT NULL
BEGIN
SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState,
Broker.EntityType, Submission.Coverage, Status.Status
FROM Submission
WHERE Status = @status
INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId
INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId
END
ELSE
SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status
FROM Submission
INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId
INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId
END
然后你可以适当地编辑你的SqlDataSource:
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:MyConnectionString %>"
SelectCommand="GetStuffByStatus" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter Name="status" ControlID="DtopDownList1" PropertyName="SelectedValue" ConvertEmptyStringToNull="true" />
</SelectParameters>
</asp:SqlDataSource>
然后,如果您不想按状态过滤,请确保使用此参数传递任何内容(DropDownList SelectedValue为空)。向DropDownList添加一个默认的空值:
<asp:DropDownList ID="DtopDownList1" runat="server" DataSourceID="SqlDataSource1" DataTextField="someidentifier" DataValueField="someidentifier" AppendDataBoundItems="true">
<asp:ListItem Text="No filter" Value="" />
</asp:DropDownList>
首先让SqlDataSource处理非过滤(空)的情况我遇到了一些麻烦,我不得不为GridView的SqlDataSource添加一个OnSelecting处理程序。我将此属性添加到SqlDataSource:
OnSelecting="SqlDataSource2_Selecting"
并编写了一个检查空案例的处理程序,并将参数设置为DBNull:
protected void SqlDataSource2_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
if (DtopDownList1.SelectedValue == String.Empty)
{
((SqlCommand)e.Command).Parameters["@status"].Value = DBNull.Value;
}
}
我已经测试了这个解决方案,它可以按照您的描述运行。
当然,执行此操作的最佳做法是编写自己的数据层,以更恰当地处理此逻辑,但这可能超出了此问题的范围。
答案 1 :(得分:1)
为了展示对我有用的东西,这是我的代码。它运作正常。关于@ashelvey的答案,虽然我没有测试他的方法,但他对参数化是正确的。我没有的唯一原因是我正在进行一个培训项目,我的处理程序特别告诉我现在要避免它。该站点不用于部署。无论如何,我原来的问题是“如何在按钮点击时更改选择命令?”这是答案:
protected void BtnStatusSearch_Click(object sender, EventArgs e)
{
SqlDataSource1.SelectCommand = "SELECT Customer.SubId, Customer.CustName, Customer.CustCity, Customer.CustState, Broker.BroName, Broker.BroState, Broker.EntityType, Submission.Coverage, Status.Status FROM Submission INNER JOIN Broker ON Broker.SubId = Submission.SubmissionId INNER JOIN Customer ON Customer.SubId = Submission.SubmissionId INNER JOIN Status ON Status.StatusId = Submission.StatusId WHERE Status.Status = '" + DdlStatus.SelectedItem.Text + "'";
SqlDataSource1.DataBind();
}