0

我需要在SQL Server 2008 R2数据库的1到3个字段中执行子字符串的全文搜索。只有具有非空搜索词的字段必须被搜索。我使用实体框架,搜索是一个更大的LINQ查询的一部分,所以它必须在表值函数中进行组合。因此,没有动态SQL可能。到目前为止,我想出了以下UDF:从UDF中的查询中排除WHERE子句的一部分

CREATE FUNCTION [dbo].[SearchPublications] 
(
@version int, 
@comment nvarchar(4000), 
@description nvarchar(4000), 
@tags nvarchar(4000) 
) 
RETURNS 
@Table_Var TABLE 
(
[ID] [int] NOT NULL, 
[IDPublicationType] [int] NOT NULL, 
[IDCover] [int] NULL, 
[IDSmallCover] [int] NULL, 
[IDContent] [int] NOT NULL, 
[Cost] [decimal](10, 2) NOT NULL, 
[Language] [smallint] NOT NULL, 
[Flags] [tinyint] NOT NULL, 
[Year] [smallint] NOT NULL, 
[Guid] [nvarchar](255) NOT NULL, 
[Key] [nvarchar](25) NOT NULL, 
[CTime] [datetime] NOT NULL 
) 
AS 
BEGIN 
declare @commentParam nvarchar(4000), @descriptionParam nvarchar(4000), @tagsParam nvarchar(4000), @guid nvarchar(32) = 'E442FB8EA8624E289BD13753480AFA8B' 
select @commentParam = isnull('"' + @comment + '*"', @guid) 
select @descriptionParam = isnull('"' + @description + '*"', @guid) 
select @tagsParam = isnull('"' + @tags + '*"', @guid) 

insert @Table_Var 
select * 
from Publications 
where (@commentParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 3 and IDVersion = @version and 
contains(LongValue, @commentParam) 
)) 
and (@descriptionParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 4 and IDVersion = @version and 
contains(LongValue, @descriptionParam) 
)) 
and (@tagsParam = @guid or exists (select 
1 from PublicationFields 
where IDPublication = Publications.ID and IDField = 5 and IDVersion = @version and 
contains(LongValue, @tagsParam)) 
) 
RETURN 
END 

然而,从搜索导致高次优查询计划和搜索服用多达10秒才能完成使用@param = @guid or...结构的排除空参数。没有所述结构的同样的搜索几乎立即返回,但是在那种情况下,我不能使用可变数量的搜索项。当动态SQL不可行时,是否有更优化的方式从查询中排除部分WHERE子句?为3个搜索参数的每个组合编写单独的TVF是我想避免的。

回答

0

回答我的问题:解决的办法是写,搜索只是一个指定字段

CREATE FUNCTION [dbo].[SearchPublications] 
( 
    @version int, 
    @field int, 
    @search nvarchar(4000) 
) 
RETURNS TABLE 
AS 
RETURN 
(
    select Publications.* 
    from Publications, PublicationFields 
    where IDPublication = Publications.ID and IDField = @field and IDVersion = @version and 
    contains(LongValue, @search) 
) 

,然后尽可能多地调用中使用相交方法的LINQ查询需要结合起来,它的功能:

if (query == null) 
{ 
    query = provider.SearchPublications(search.IDVersion, id, string.Format("\"{0}*\"", value)); 
} 
else 
{ 
    query = query.Intersect(provider.SearchPublications(search.IDVersion, id, string.Format("\"{0}*\"", value))); 
}