为什么我的SQL查询不工作,因为我想?



我正在为ASP中的用户管理项目工作。. NET Web应用程序(Framework 4.8)。在代码中已经使搜索框,我希望能够搜索的名称,EmployeeNumber,如果他们被排除与否。我使用它作为过滤器,所以我不需要在gridview中滚动所有页面。我在查询中尝试了一些变化,但似乎没有什么不同。我对这些SQL查询不太熟悉,你知道的。

所以我想知道是否有人可以简单地向我解释我的查询到底出了什么问题,为什么?

PopulateGridView:

void PopulateGridView()
{
string find = "select * from TBL_USERS where (Name like '%' + @Name + '%') or (employee like '%' + @Employee + '%') and (case when excluded =1 then 'True' else 'False' end like '%false%')";
SqlCommand comm = new SqlCommand(find, con);
comm.Parameters.Add("@Name", SqlDbType.VarChar, 255).Value = TextBox1.Text;
comm.Parameters.Add("@Employee", SqlDbType.VarChar, 32).Value = TextBox1.Text;
comm.Parameters.Add("@Excluded", SqlDbType.Bit, 1).Value = 1;
con.Open();
comm.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = comm;
DataSet ds = new DataSet();
da.Fill(ds, "Name");
da.Fill(ds, "Employee");
da.Fill(ds, "Excluded");
gvTestUsers.DataSource = ds;
gvTestUsers.DataBind();
con.Close();

}

您的主要问题似乎是OR周围缺少括号。您想要哪种类型的过滤并不完全清楚:您是想搜索两个值,还是只想搜索非空值。您可能需要调整条件

你的c#代码应该是这样的

void PopulateGridView()
{
const string find = @"
select *
from TBL_USERS
where (Name like '%' + @Name + '%' or employee like '%' + @Employee + '%')
and excluded = @Excluded
";
using(var con = new SqlConnection(YourConnString))
using(var comm = new SqlCommand(find, con))
{
comm.Parameters.Add("@Name", SqlDbType.VarChar, 255).Value = TextBox1.Text;
comm.Parameters.Add("@Employee", SqlDbType.VarChar, 32).Value = TextBox1.Text;
comm.Parameters.Add("@Excluded", SqlDbType.Bit).Value = 1;
con.Open();
var dt = new DataTable();
using(var reader = comm.ExecuteReader())
{
dt.Load(reader);
}
gvTestUsers.DataSource = dt;
gvTestUsers.DataBind();
}            
}
  • 注意使用连接对象,而不是缓存
  • 注意using
  • 请注意,查询字符串是const,这使得您不太可能获得向其中注入数据的渴望
  • 由于您只有一个表,您可以将其放入DataTable
  • 适配器只有在您有现有数据要与
  • 合并时才有用

当我在框中放入Name时,gridview将显示所有具有该Name的用户。当我在框中放入Employeenumber时,它将只显示一个与该Employeenumber完全相同的用户

我个人会使用不同的查询,例如,如果EmployeeNumber是一个整数/你可以告诉用户想要什么从他们输入。尝试进行动态查询时,如果您有一堆参数都是错误的,那么通常计划非常糟糕,性能也很差。使用目标where子句构建SQL比将N个不同的参数拼凑在一起更可取。

我会用Dapper:

if(!int.TryParse(TextBox.Text)) //by name
gvTestUsers.DataSource = con.Query<User>(
@"select * from TBL_USERS where Name LIKE @Name AND excluded=0", 
new { Name = "%" + TextBox.Text + "%" }
).AsList();
else //employee 
gvTestUsers.DataSource = con.Query<User>(
@"select * from TBL_USERS where EmployeeNumber = @Emp AND excluded=0", 
new { Emp = TextBox.Text }
).AsList();

如果EmployeeNumber字母数字的(和你真正"contains"和你没有任何方式告诉如果他们输入姓名或号码,然后或可能的方式有:

gvTestUsers.DataSource = con.Query<User>(
@"select * from TBL_USERS where (Name LIKE @X OR EmployeeNumber LIKE @X) AND excluded=0", 
new { X= "%" + TextBox.Text + "%" }
).AsList();

是的. .这就是你用Dapper所要做的(在创建一个SqlConnection con之后)——它处理所有的参数,运行查询,检索结果,把它们变成你的User类的实例。(我相信你有,对吧?如果您正在使用支持记录的c#版本,则可以像record User(string Name, int EmployeeNumber, ...))

一样简单。相比之下,处理数据表要痛苦得多;所有的东西都是字符串类型的,需要从对象一直强制转换。可怕的

,

但是,如果您想继续使用SqlDataAdapter,它看起来像:

var dt = new DataTable;
var da = new SqlDataAdapter("select * from TBL_USERS where (Name LIKE @X OR EmployeeNumber LIKE @X) AND excluded=0", connstringhere);
da.SelectCommand.Parameters.Add("@X", SqlDbType.VarChar, 255).Value = "%"+ TextBox.Text + "%";
da.Fill(dt);
gvTestUsers.DataSource = dt;
gvTestUsers.DataBind();

如果您希望名称匹配是模糊的,但为空no。为了准确匹配,将查询翻转到Name LIKE '%' + @X + '%' OR EmployeeNumber = @X

关于数据适配器是否需要处理存在一些争论;微软在他们的例子中没有这样做,但有些人觉得"它是一次性的,它应该被处理掉"。-在var之前添加using会这样做,如果你属于这个阵营

相关内容

最新更新