2014-11-20 6 views
-1

У меня есть две таблицыДинамические условия без динамического SQL

KeyWord Table 
    | KeyWord1 | Operator |  KeyWord2 | 
    | -----------|------------:|:------------:| 
    | Tom  |  AND |  Harry | 
    | Krishna |  OR |  Radha | 
    | Raju  |  AND |  Radha | 

Text Table 

    | Id   |  Text      | 
    | -----------|-------------------------------:| 
    | 1   |  Tom and Harry Nice  | 
    | 2   |  Tom Harry Raju Radha Nice| 
    | 3   |  Raju Radha Tom Nice  | 

Ожидаемый результат

Результат

| Id   |  Text      | 
    | -----------|-------------------------------:| 
    | 2   |  Tom Harry Raju Radha Nice| 

В результате из-за (Tom AND Harry) AND (Krishna OR Radha) AND (Raju AND Radha). Мне нужно использовать оператор LIKE (LIKE '%'+tbl.Text+'%'), чтобы получить логическое выражение.

Если нет динамического подхода sql, дайте мне знать лучший динамический подход sql.

+2

Все преимущества динамического SQL имеют такие динамические условия. Почему вы не хотите использовать динамический SQL? – mattytommo

+0

@mattytommo легко читается и поддерживается. Кроме того, запрос будет намного длиннее, если таблица условий будет большой. вероятность медленного запроса? –

+0

Итак, вы считаете, что хранить операнды и ключевые слова для поиска в таблице легко поддерживать? Я думаю, что он вышел из окна, когда задумал этот стол. – mattytommo

ответ

0

Я не уверен, есть ли другой способ обойтись без динамического SQL. Попробуйте под кодом, это наверняка поможет вам. Я пробовал в sybase, это работало потрясающе!

--Create Sample Tables 
 
--Keyword Table 
 
create table #tempKeyword 
 
(col_id numeric(5,0) identity , Keyword1 varchar(100),Operator varchar(100),Keyword2 varchar(100)) 
 

 
insert into #tempKeyword (Keyword1,Operator,Keyword2) 
 
select * 
 
from 
 
(
 
select 'Tom' as Keyword1, 'AND' as Operator, 'Harry' as Keyword2 
 
union all 
 
select 'Krishna' as Keyword1, 'OR' as Operator, 'Radha' as Keyword2 
 
union all 
 
select 'Raju' as Keyword1, 'AND' as Operator, 'Radha' as Keyword2 
 
) a 
 

 
print 'Keyword Table' 
 
select * from #tempKeyword 
 

 

 
--Text table 
 
select * into #tempText from 
 
(
 
select 1 as Id, 'Tom and Harry Nice' as Text 
 
union all 
 
select 2 as Id, 'Tom Harry Raju Radha Nice' as Text 
 
union all 
 
select 3 as Id, 'Raju Radha Tom Nice' as Text 
 
) b 
 

 
print 'Text Table' 
 
select * from #tempText 
 

 
SET NOCOUNT ON 
 

 
---- Script begin 
 
declare @Keyword1 varchar(100) 
 
declare @Operator varchar(100) 
 
declare @Keyword2 varchar(100) 
 
declare @sql varchar(1000) 
 

 
--settin loop counter variables 
 
declare @start int 
 
declare @end int 
 
select @start=min(col_id),@end=max(col_id) from #tempKeyword 
 

 
--loop for #temp table 
 
WHILE (@start <= @end)    
 
BEGIN 
 

 
    select top 1 @Keyword1=Keyword1,@Operator=Operator,@Keyword2=Keyword2 
 
    from #tempKeyword where [email protected] 
 

 
    --eliminate each rows with NOT condition from result table. 
 
    select @sql='delete from #tempText where not (Text like ''%' + @Keyword1 + 
 
    '%''' + @Operator +' Text like ''%' + @Keyword2 + '%'')' 
 
    execute(@sql) 
 
    
 
    --set Counter for Loop 
 
    set @start = @start + 1 
 
end 
 

 
SET rowcount 0 
 
--Result Output 
 
print 'Results' 
 
select * from #tempText

Я надеюсь, что это помогает :)

1

следующие работы без динамического SQL или курсоров/в то время как-петли. Несколько замечаний по этому поводу:

  • С «текст» является зарезервированным словом, я переименовал:
    • [Текст] таблица будет [ЬЬеТехЬ]
    • [Текст], чтобы быть [ЬЬеТехЬ ]
  • Он использует коррелированные НЕ СУЩЕСТВУЕТ для выброса недопустимых записей. Это работает из-за:
    • всех множеств «ключевого слова» являются «И» объединено, следовательно, они должны быть истинными
      • все они должны быть истинными, следовательно, любые один из них, что является ложным аннулирует запись
      • одно ложное условие дает тот же ответ, как и все правильные условия, если только поставить NOT перед EXISTS
      • оно гораздо легче искать одного несоответствия, чем убедиться, что все тестовые случаи совпадение
      • поскольку мы ищу обратную/противоположность условий (как отмечено в таблице ключевых слов), мы реверс И/ИЛИ логику с помощью:
        • Верных и Истинные => НЕ Правда ИЛИ НЕ Правда
        • Правды ИЛИ Правда => НЕ Правда И нЕ Правда
  • OR условие, установленное в тестовых данных не является хорошим тестом, поскольку это имеет значение, которое требуется по одному из AND наборов условий (т.е. Radha), поэтому набор OR не нужен и не поможет определить, работает ли логика как для AND, так и для OR условий.Итак:
    • Я изменил имя Radha к Bob
    • Я добавил 4-ую строку в [ЬЬеТехЬ], что имеет Krishna и которая является единственной строкой, должно (и делает!) Матч

Код:

DECLARE @TheText TABLE (ID INT, TheText NVARCHAR(500)); 
INSERT INTO @TheText VALUES (1, N'Tom and Harry Nice'); 
INSERT INTO @TheText VALUES (2, N'Tom Harry Raju Radha Nice'); 
INSERT INTO @TheText VALUES (3, N'Raju Radha Tom Nice'); 
INSERT INTO @TheText VALUES (4, N'Tom Harry Raju Radha Krishna Nice'); 

DECLARE @Keywords TABLE (
    Keyword1 NVARCHAR(100) NOT NULL, 
    Operator NVARCHAR(10) NOT NULL, 
    Keyword2 NVARCHAR(100) NOT NULL 
); 
INSERT INTO @Keywords VALUES ('Tom', 'AND', 'Harry'); 
INSERT INTO @Keywords VALUES ('Krishna', 'OR', 'Bob'); 
INSERT INTO @Keywords VALUES ('Raju', 'AND', 'Radha'); 

SELECT * 
FROM @TheText txt 
WHERE NOT EXISTS (
      SELECT * 
      FROM @Keywords kw 
      WHERE (
         kw.Operator = N'AND' 
       AND (
         txt.TheText NOT LIKE N'%' + kw.Keyword1 + N'%' 
        OR  txt.TheText NOT LIKE N'%' + kw.Keyword2 + N'%' 
        ) 
       ) 
      OR  (
         kw.Operator = N'OR' 
       AND (
         txt.TheText NOT LIKE N'%' + kw.Keyword1 + N'%' 
        AND txt.TheText NOT LIKE N'%' + kw.Keyword2 + N'%' 
        ) 
       ) 
     ); 

Результат:

ID TheText 
4 Tom Harry Raju Radha Krishna Nice 
Смежные вопросы