我试图为我的程序制作搜索方法。在搜索页面中,用户可以搜索8个变量。例如,如果用户仅键入"名称:"此方法将根据名称进行选择。如果用户决定输入" Id:"此外,此方法将根据两者进行选择。我原来有8个变量。
嗯......每当我尝试搜索时,我都会得到#34;列' ......不存在"信息。如果我只输入名称,则会显示列'名称'不存在。同样适用于Id,除了它表示cloumn' Id'不存在。
我无法弄清问题是什么。它可能与准备好的陈述有关。我的空搜索顺便说一下。
public ObservableCollection<Foo> Search(Foo foo)
{
ObservableCollection<Foo> results = new ObservableCollection<Foo>();
IdParam = new NpgsqlParameter("@Id", NpgsqlTypes.NpgsqlDbType.Bigint);
NameParam = new NpgsqlParameter("@Name", NpgsqlTypes.NpgsqlDbType.Varchar, 50);
string sql;
//Null search
if (intern == null)
sql = "select * from \"Foos\"";
else
{
sql = "select * from \"Foos\" ";
int parameterCount = 0;
//This part goes too long, So I just put 2 sample of it. I have 8 parameters in the
//original
if (foo.Id > 0)
{
if (parameterCount == 0)
sql += "WHERE \"Id\"=";
if (parameterCount > 0)
sql += "AND \"Id\"=";
IdParam.Value = foo.Id;
sql += "@Id ";
parameterCount++;
}
if (foo.Name != "" && foo.Name != null)
{
if (parameterCount == 0)
sql += "WHERE \"Name\"=";
if (parameterCount > 0)
sql += "AND \"Name\"=";
NameParam.Value = foo.Name;
sql += "@Name ";
parameterCount++;
}
}
try
{
NpgsqlCommand cmd = new NpgsqlCommand(sql, dbConnection);
NpgsqlDataReader dr = cmd.ExecuteReader(); //This line gives the error
Intern result = new Intern();
while (dr.Read())
{
result.Id = (long)dr.GetInt64(dr.GetOrdinal("Id"));
result.Name = dr.GetString(dr.GetOrdinal("Name"));
results.Add(result);
result = new Intern();
}
return results;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return null;
}
}
当我不使用准备好的陈述时,它有效!
if (intern.Id > 0)
{
if (parameterCount == 0)
sql += "WHERE \"Id\"=";
if (parameterCount > 0)
sql += "AND \"Id\"=";
//IdParam.Value = intern.Id;
//sql += "@Id ";
sql += intern.Id + " "; //When I do this, it works.
parameterCount++;
}
我该怎么做才能解决这个问题?
答案 0 :(得分:0)
构建SQL字符串是一个充满问题的做法。正如您现在所看到的,故障排除是一个真正的痛苦。然后那个人你必须明白当他试图去做的时候会发生什么......
一种方法是编写查询,因此不需要执行文本更改。如:
@SQL = "select * from \"foos\" "
+ "where (@ID is null or \"ID\" = @ID) "
+ " and (@Name is null or \"Name\" = @Name) "
+ " and (@so_forth...)"
因此,如果@Name中有值,则它不会为null,并且该值将用于检查列。如果没有,它将为空并且跳过测试(将其读作&#34; ...和TRUE和......&#34;。
关键是,现在每次都执行相同的查询,只有值会发生变化。当事情没有按照你认为应该的方式运作时,更容易进行故障排除。
答案 1 :(得分:0)
好吧,我忘了在我的命令中添加参数,这就是我收到此错误的原因。
所以我修好了,它有用了!
if (intern.Id > 0)
{
if (parameterCount == 0)
sql += "WHERE \"Id\"=";
if (parameterCount > 0)
sql += "AND \"Id\"=";
IdParam.Value = intern.Id;
sql += "@Id ";
cmd.Parameters.Add(IdParam);
parameterCount++;
}
if (intern.Name != "" && intern.Name != null)
{
if (parameterCount == 0)
sql += "WHERE \"Name\" ILIKE ";
if (parameterCount > 0)
sql += "AND \"Name\" ILIKE ";
NameParam.Value = intern.Name;
sql += "@Name ";
cmd.Parameters.Add(NameParam);
parameterCount++;
}