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

本文关键字:关键字 列表 一个 是否 何验证 验证 SQL- 字段 存在 | 更新日期: 2023-09-27 18:28:52

我有一个Keywords表,其中包含字段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)
        )

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

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

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

EDIT:如果值字段中有多个关键字,则可以使用split函数。例如:

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

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

可能表现不佳,但可能值得一试:

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

让存储过程为包含关键字的列的内容创建一个临时表,然后查看两个列表的UNION和临时表之间是否有交集,你会怎么想?

这是你知道怎么做的吗(可能需要一个用户定义的函数来将字段拆分成一个表),如果不是,你在使用什么数据库后端(很抱歉,如果c#代码中有什么东西应该提示我,我看不到)