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 Server 2008,可以使用表值参数将关键字列表传递给存储过程。您可以像在join
或in
子句中使用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#代码中有什么东西应该提示我,我看不到)