SQL - 如何验证字段中是否存在关键字列表中至少1个关键字

时间:2012-03-23 13:36:55

标签: c# sql

我有一个关键字表格,其中包含字段KeywordsEn和KeywordsFr。 我有另一个带有字段值的MediaObjectsMetadata。

我需要检查Value字段是否包含Keywords表中的至少一个单词(在KeywordsEn或KeywordsFr字段中)。

我以为我会像这样使用Contains函数,其中@priorityKeywords包含与OR连接的所有KeywordsEn和KeywordsFr,但是我的字符串中有超过16000个字符,而Contains函数只能允许4000。

我的SP的一部分

SELECT FKMediaObjectId
FROM dbo.gs_MediaObjectMetadata
WHERE UPPER([Description]) = 'KEYWORDS'
AND FKMediaObjectId >= 
  (SELECT TOP 1 MediaObjectId 
  FROM dbo.gs_MediaObject 
  WHERE DateAdded > @lastcheck 
  ORDER BY MediaObjectId) 
  AND Contains([Value] , @priorityKeywords);

生成@priorityKeywords的C#函数

public static string GetPriorityKeywordsList()
{
  string keywordString = String.Empty;

  using (IDataReader dr = GetCommandPriorityKeywordsList().ExecuteReader(CommandBehavior.CloseConnection))
  {
    while (dr.Read())
    {
      if (keywordString.Length > 0)
      {
         keywordString += " OR ";
      }
      // max 4000 chars allowed in COntains sql function of sp
      keywordString += "'" + dr["KeywordEn"].ToString() + "' OR '" + dr["KeywordFr"].ToString() + "'";
     }
    }
        return keywordString;
}

您建议我的存储过程使用哪种解决方案?

编辑(解决方案):

以下是Andomar提出的解决方案,适应我的情况:

select  *
from    gs_MediaObjectMetadata yt
where   
UPPER([Description]) = 'KEYWORDS'
AND  not exists
        (
        select  *
        from    dbo.fnSplit(Replace(yt.Value, '''', ''''''), ',') split
        where   split.item in (select KeywordEn from gs_Keywords) or split.item in (select KeywordFr from gs_Keywords)
        )

3 个答案:

答案 0 :(得分:0)

如果您使用的是SQL Server 2008,则可以使用表值参数将关键字列表传递给存储过程。您可以在tablejoin子句中使用变量,就像使用in一样。例如:

use testdatabase
go
if exists (select * from sys.procedures where name = 'TestProc')
    drop procedure TestProc
if exists (select * from sys.types where name = 'TestProcList')
    drop type TestProcList
go
create type TestProcList as table (keyword varchar(50))
go
create procedure dbo.TestProc(
    @list TestProcList readonly)
as
select  *
from    YourTable
where   value in (select keyword from @list)
go

编辑:如果您在值字段中有多个关键字,则可以使用split function。例如:

select  *
from    YourTable yt
where   not exists
        (
        select  *
        from    dbo.fnSplit(yt.value, " ") split
        where   split.item not in (select keyword from @list)
        )

这要求值列中的所有关键字(用空格分隔)都出现在@list参数中。

答案 1 :(得分:0)

可能性能不佳,但值得一试:

select * from MediaObjectsMetadata m
where exists 
(select null from Keywords k
 where m.values like '%' & k.KeywordEn & '%' or
       m.values like '%' & k.KeywordFr & '%' )

答案 2 :(得分:0)

您如何考虑让存储过程创建包含关键字的列内容的临时表,然后查看两个列表的UNION和临时表之间是否存在任何交集?

这是你知道怎么做的事情(可能需要用户定义的函数将字段拆分为表),如果没有,你使用的是什么数据库后端(抱歉,如果c#代码中有什么东西应该提示我离开了,我没有看到它)