我有一个关键字表格,其中包含字段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)
)
答案 0 :(得分:0)
如果您使用的是SQL Server 2008,则可以使用表值参数将关键字列表传递给存储过程。您可以在table
或join
子句中使用变量,就像使用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#代码中有什么东西应该提示我离开了,我没有看到它)