2012-03-23 55 views
1

我有一個關鍵字表,其中包含字段KeywordsEn和KeywordsFr。 我有另一個MediaObjectsMetadata字段值。SQL - 如何驗證一個字段中是否存在至少一個關鍵字列表

我需要檢查「值」字段是否至少包含關鍵字表格中的一個單詞(在關鍵字En或KeywordsFr字段中)。

我想我會用包含這樣的功能,其中@priorityKeywords包含所有KeywordsEn和KeywordsFr用OR連接起來,但後來我在我的字符串超過16000個字符,包含的功能不僅可以讓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); 

C#函數生成@priorityKeywords

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

也許你可以只執行SQL多次,保持你的字符串在4000字符的限制,然後加入結果? – 2012-03-23 13:49:57

+0

我可以,我只想知道是否有一個理想的解決方案,其性能將處於最佳狀態。有很多記錄可以運行這個(它是一個非常大的相冊)... – crichard 2012-03-23 13:53:23

回答

0

如果您使用SQL Server 2008中,您可以使用表值參數將關鍵字列表傳遞給存儲過程。您可以像使用table那樣在joinin子句中使用該變量。例如:

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參數。

+0

哦,但我可能在值字段中有多個關鍵字,並且此解決方案在這種情況下不起作用... – crichard 2012-03-23 14:22:53

+0

I值字段中至少需要1個關鍵字才能出現在關鍵字表中,但並非全部都是必需的。 – crichard 2012-03-23 14:54:49

+0

現在很好用。謝謝 ! – crichard 2012-03-23 15:04:46

0

或許不會表現良好,但可能是值得一試:

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

LIKE關鍵字是否使用FullText標記,如果它們存在? – 2012-03-23 14:00:46

0

,你有什麼看法具有存儲過程創建包含關鍵字列的內容的臨時表,然後看是否兩個列表的UNION和臨時表之間有任何交集?

是你知道該怎麼做的事情(可能需要一個用戶定義的函數來將字段拆分爲表),如果不是,你使用了哪個數據庫後端(抱歉,如果在c#代碼中有某些東西應該我沒有看到它)

相關問題