【发布时间】:2014-03-04 15:12:17
【问题描述】:
- 我有一个搜索字段,允许用户输入空格分隔字词。
- 我需要从数据库中的几个表中搜索5列中的每个单词。
- 我想创建一个可以从我的C# Web 服务(实体框架)调用的数据库函数。
目前,我使用这个:
CREATE FUNCTION [dbo].[SEARCH_SINGLE] (
@langId INT = 4,
@searchString VARCHAR(MAX) = NULL
)
RETURNS TABLE
AS
RETURN
WITH words AS (
SELECT * FROM [dbo].splitstring(@searchString, ' ')
)
SELECT DISTINCT
...
FROM
...
WHERE
...
AND (
EXISTS(SELECT t2.Name FROM words t2 WHERE a.[FIRSTNAME] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE a.[LASTNAME] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE c.[CITY] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE j.[PROMO_YEAR] like '%'+t2.Name+'%')
OR EXISTS(SELECT t2.Name FROM words t2 WHERE e.[EMPLOYOR] like '%'+t2.Name+'%')
)
它有效,但它返回匹配一个输入的单词的所有记录。 我需要返回匹配至少一列中的所有单词的记录。
例如,如果我们只考虑firstname 和lastname:
- “John”应返回“John Doe”、“John Bieber”、“John Daney”等。
- “John D%”应返回“John Doe”和“John Daney”
- “John Doe”应该只返回“John Doe”。
实际上,对于像“John Doe McDonald”这样的搜索,我需要像这样模拟WHERE:
WHERE
(
a.[FIRSTNAME] like '%John%'
OR a.[LASTNAME] like '%John%'
OR c.[CITY] like '%John%'
OR j.[PROMO_YEAR] like '%John%'
OR e.[EMPLOYOR] like '%John%'
)
AND (
a.[FIRSTNAME] like '%Doe%'
OR a.[LASTNAME] like '%Doe%'
OR c.[CITY] like '%Doe%'
OR j.[PROMO_YEAR] like '%Doe%'
OR e.[EMPLOYOR] like '%Doe%'
)
AND (
a.[FIRSTNAME] like '%McDonald%'
OR a.[LASTNAME] like '%McDonald%'
OR c.[CITY] like '%McDonald%'
OR j.[PROMO_YEAR] like '%McDonald%'
OR e.[EMPLOYOR] like '%McDonald%'
)
理想情况下,如果在整个数据库的 5 列中都没有找到某个单词,则只需忽略它(“John Doe sjdhf67df”应该返回“John Doe”...)。
我尝试动态构建查询,但在返回结果时遇到了一些问题,因为我们不能在函数中使用 EXEC...
我们目前不考虑全文搜索!
如何修改我的函数以获得预期结果?
【问题讨论】:
-
“我们暂时不考虑全文搜索!”。为什么不呢?
-
我被要求创建一个简单的搜索功能,而无需在数据库级别(索引等)进行太多修改。由于搜索是跨多个表完成的,所以我在网上看到的内容让我觉得这是很多工作。
-
我几乎不会认为您的要求很简单。尝试解析单个条目并检查空格、通配符等,然后知道将各个部分应用于哪个列听起来很痛苦。修改前端是一种选择吗?如果您可以让您的用户选择他们想要搜索的字段并输入一个单词,这将更容易。如果他们想搜索多个字段,让他们能够添加更多搜索条件。
-
我们已经有一个“自定义搜索”,用户可以在其中选择他们想要搜索的字段。但要求是有第二个“简单搜索”,允许用户使用单个文本字段进行搜索。老实说,我目前有一个使用完整 C#、LINQ 和实体框架的工作解决方案,但我想以数据库方式进行。
标签: sql sql-server function search sql-like