高效搜索数据库

时间:2012-06-26 16:47:44

标签: oracle search jdbc oracle11g

我有一个包含用户详细信息的数据库。我没有'firstname'和'lastname'的单独列。我只使用了一个列:'name'。我的查询是这样的:

ps_details=con.prepareStatement("select * from student_details where name=?");  
ps_details.setString(1,name);

问题是:

在db中,名称存储在大写字母中。因此,当用户以小写或混合大小写输入他/她的名字时,搜索不成功。这个问题的有效解决方案是什么?

此外,如果'name'以小写,混合大小写以及大写形式存储在db中,即如果事先不知道该情况,该怎么办?我也想使用like子句

我正在使用Oracle 11g Express Editon。

3 个答案:

答案 0 :(得分:3)

如果你真的打算做一个完全匹配(即用户需要输入他们的全名来进行搜索,而不是只输入他们名字的一部分),你可以将表达式的两面都包含在UPPERLOWER函数。

SELECT *
  FROM student_details
 WHERE upper(name) = upper(?)

但是,如果您这样做,Oracle将无法在name上使用索引,因此必须扫描整个表。这不是特别有效。您可以通过在upper(name)

上创建基于函数的索引来解决该问题
CREATE INDEX idx_upper_name
    ON student_details( upper(name) );

但实际上,我怀疑你不想做基于外卡的比赛。您几乎肯定希望允许用户输入名称的某些部分并返回包含该字符串的结果。因此,如果我是学生,您可能希望允许用户搜索“Justin”或“Cave”或“Justin Cave”或“Just”,并让所有这些搜索返回我的行(以及其他任何匹配的行,当然)。如果你想这样做,最简单的方法是使用LIKE函数和%通配符

SELECT *
  FROM student_details
 WHERE upper(name) like '%' || upper(?) || '%'

将返回在您正在搜索的文本中的任何位置找到输入字符串的所有行。但这实际上使我们在性能方面回到接近正方形的位置 - 拥有领先的通配符将使Oracle很难从使用我们在UPPER(name)上定义的索引中受益。这就是为什么大多数人会分别存储名字和姓氏的原因。这允许他们做类似

的事情
SELECT *
  FROM student_details
 WHERE upper(first_name) like upper(?) || '%'
    OR upper(last_name) like upper(?) || '%'

这允许他们返回我的行,无论用户是搜索“Justin”还是“Cave”或“Just”,而不管数据库中的数据大小或搜索中输入的数据。并且它能够对数据使用适当的基于函数的索引。

答案 1 :(得分:2)

UPPER - upper函数将指定字符串中的所有字母转换为大写。在变量(用户输入)和表列值上使用它,将它们转换为相同的大小写以进行比较以处理这两个问题。 (你也可以使用更低 - 想法是将两者转换为相同的情况进行比较)。 * 仅使用后期通配符*

进行编辑
select * from student_details where UPPER(name) like UPPER(?) || '%'

你必须玩,但我认为你也可以使用通配符执行以下操作。

ps_details=con.prepareStatement("select * from student_details where UPPER(name) like UPPER(?)");  
ps_details.setString(1,name%);

答案 2 :(得分:1)

尝试在输入中使用UPPER()。