Oracle 数据库中的高效搜索
我有一个包含用户详细信息的数据库。“firstname”和“lastname”没有单独的列。我只使用了一列:“name”。我的问题是这样的:Oracle 数据库中的高效搜索,oracle,search,jdbc,oracle11g,Oracle,Search,Jdbc,Oracle11g,我有一个包含用户详细信息的数据库。“firstname”和“lastname”没有单独的列。我只使用了一列:“name”。我的问题是这样的: ps_details=con.prepareStatement("select * from student_details where name=?"); ps_details.setString(1,name); 问题是: 在db中,名称以大写形式存储。因此,当用户以小写或混合大小写键入其姓名时,搜索将失败。这个问题的有效解决方案是什么 此外,如
ps_details=con.prepareStatement("select * from student_details where name=?");
ps_details.setString(1,name);
问题是:
在db中,名称以大写形式存储。因此,当用户以小写或混合大小写键入其姓名时,搜索将失败。这个问题的有效解决方案是什么
此外,如果“name”以小写、混用和大写形式存储在db中,也就是说,如果事先不知道大小写,该怎么办。我还想使用like子句 我正在使用Oracle 11g Express Editon。尝试在输入中使用UPPER()。尝试在输入中使用UPPER()。-UPPER函数将指定字符串中的所有字母转换为大写。对变量(用户输入)和表列值都使用它,将它们转换为相同的大小写进行比较,以处理这两个问题。(您也可以使用lower-其目的是将两者转换为同一个案例进行比较)*仅使用后加码通配符为LIKE编辑* 你必须使用它,但我认为你也可以使用通配符执行以下操作
ps_details=con.prepareStatement("select * from student_details where UPPER(name) like UPPER(?)");
ps_details.setString(1,name%);
-上限函数将指定字符串中的所有字母转换为大写。对变量(用户输入)和表列值都使用它,将它们转换为相同的大小写进行比较,以处理这两个问题。(您也可以使用lower-其目的是将两者转换为同一个案例进行比较)*仅使用后加码通配符为LIKE编辑*
你必须使用它,但我认为你也可以使用通配符执行以下操作
ps_details=con.prepareStatement("select * from student_details where UPPER(name) like UPPER(?)");
ps_details.setString(1,name%);
如果您确实希望进行精确匹配(即,用户需要输入其全名才能进行搜索,而不仅仅是输入其姓名的一部分),则可以在
上部
或下部
函数中包装表达式的两侧
SELECT *
FROM student_details
WHERE upper(name) = upper(?)
但是,如果这样做,Oracle将无法在name
上使用索引,因此必须扫描整个表。这不是特别有效。您可以通过基于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”,也不管数据库中数据的大小写或搜索中输入的数据。并且它能够根据数据使用适当的基于函数的索引。如果您真的想进行精确匹配(即,用户需要输入他们的全名才能进行搜索,而不仅仅是输入他们姓名的一部分),您可以在
上部
或下部
函数中包装表达式的两侧
SELECT *
FROM student_details
WHERE upper(name) = upper(?)
但是,如果这样做,Oracle将无法在name
上使用索引,因此必须扫描整个表。这不是特别有效。您可以通过基于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”,也不管数据库中数据的大小写或搜索中输入的数据。它能够根据数据使用适当的基于函数的索引。如果已知源代码总是大写,我不会使用大写(name),只使用name=UPPER(?)。如果名称上有一个索引,使用UPPER(名称)将不允许使用该索引(至少效率不高)。OP post说这并不总是正确的,并询问该怎么做。请参阅OP中的文本:“此外,如果‘name’以小写形式存储在db中,该怎么办?”我还想使用clause@Craig考虑在上边(name)上实现一个基于函数的索引。请考虑关于上(name)索引的注释——我只讨论了问题-案例敏感度。我不使用UPPER(name),只使用name=UPPER(?)?