2016-11-30 55 views
2

我需要構建一個查詢,其中的條件必須與數據庫中的通配符匹配。在數據庫中使用通配符查詢SQL Server

舉一個例子,它將是最清晰的。

我有一個像這樣的字段的列963-4-AKS~M2RN21AXA150~~~0C1D1D~~XX~ char是通配符。 所以下面的規定 - 必須匹配:

  • ~63-4-AKS~M
  • 963-4-AKS1M
  • 963-4-AKS~M2RN21AXA150AAA
  • 963-4-AKSAM2RN21AXA150AAA
  • 963-4-AKSCM2RN21AXA150A060C1D1DSDXX
  • 963-4-AKS~M2RN21AXA150~~~0C1D1D~~XX

我試過這麼多東西我的頭疼:(

以另一種方式(用通配符從標準)沒問題,容易。但這樣我找不到鑰匙。

問題是當我在它不匹配的字段中有一個~。因此,這裏只有第一和最後一場比賽用下面的語句:

SELECT myField FROM myTable WHERE myField LIKE REPLACE('%' + myCriteria + '%', '~', '_');

+0

用'%'替換'〜'。 –

+1

你爲什麼認爲我做了'REPLACE('%'+ myCriteria +'%','〜','_')'? '_'是一個字符的通配符 – Shadam

+0

但是你只說了第一個和最後一個匹配。所以我提供了另一種解決方案。 –

回答

1

看來模式和領域調整到左邊。
如果確實如此,我的頭低垂(充滿悲傷),這是一個功能。

create function is_a_match (@myField varchar(100),@myCriteria varchar(100)) 
returns bit 
as 
begin 

    declare @i     int = 0 
      ,@is_a_match  bit = 1 
      ,@len_myField  int = len(@myField) 
      ,@len_myCriteria int = len(@myCriteria) 
      ,@myField_c   char(1) 
      ,@myCriteria_c  char(1) 

    While 1=1 
    begin 

     set @i += 1 

     if @i > @len_myCriteria break 

     if @i > @len_myField  
     begin 
      set @is_a_match = 0 
      break 
     end 

     set @myField_c = substring(@myField ,@i,1) 
     set @myCriteria_c = substring(@myCriteria,@i,1) 

     if not (@myField_c = '~' or @myCriteria_c = '~' or @myField_c = @myCriteria_c) 
     begin 
      set @is_a_match = 0 
      break 
     end 

    end 

    return @is_a_match 
end 

GO 

select  myCriteria 
      ,dbo.is_a_match (myField,myCriteria) as is_a_match 

from  (values ('~63-4-AKS~M'       ) 
        ,('963-4-AKS1M'       ) 
        ,('963-4-AKS~M2RN21AXA150AAA'   ) 
        ,('963-4-AKSAM2RN21AXA150AAA'   ) 
        ,('963-4-AKSCM2RN21AXA150A060C1D1DSDXX' ) 
        ,('963-4-AKS~M2RN21AXA150~~~0C1D1D~~XX' ) 
        ,('963-4-AKS~M2RN21AXA150~~~0C1X1D~~XX' ) 
        ,('963-4-AKS~M2RN21AXA150~~~0C1D1D~~XXYY') 

      ) c (myCriteria) 
      ,(values ('963-4-AKS~M2RN21AXA150~~~0C1D1D~~XX' ) 
      ) f (myField) 

+---------------------------------------+------------+ 
| myCriteria       | is_a_match | 
+---------------------------------------+------------+ 
| ~63-4-AKS~M       | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKS1M       | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKS~M2RN21AXA150AAA    | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKSAM2RN21AXA150AAA    | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKSCM2RN21AXA150A060C1D1DSDXX | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKS~M2RN21AXA150~~~0C1D1D~~XX | 1   | 
+---------------------------------------+------------+ 
| 963-4-AKS~M2RN21AXA150~~~0C1X1D~~XX | 0   | 
+---------------------------------------+------------+ 
| 963-4-AKS~M2RN21AXA150~~~0C1D1D~~XXYY | 0   | 
+---------------------------------------+------------+ 

你的領域和模式之間的混合。
該字段可能不包含通配符。

E.g. 這是不是因爲「A的

963-4-AKS〜M2RN21AXA150 ~~~ 0C1D1D ~~ XX
963-4-AKS 的匹配A M2RN21AXA150 AAA

+0

這不是我,它是客戶端。我試圖解釋他,但沒有結果:( – Shadam

+0

是的,在你的例子中,如果第一個在數據庫中,第二個必須匹配。正如我所說的,以另一種方式沒有問題,但是這樣很難。 – Shadam

+0

@ Shadam,查看更新後的答案... –

0

如果你能收緊通配符的限制,你可能在這裏有戰鬥機會。我的意思是,如果在持久數據中出現通配符,則會生成有效的排列。然後用您現有的查詢查詢排列。

但是,如果每個通配符有36個可能的選項,這會變成指數級的痛苦。

+0

這是一個NVARC HAR(100)'字段和其中的每一個f ******字符都可以是通配符。我的客戶很瘋狂,不明白這會如何破壞應用程序的性能。 – Shadam

+0

該字符串感覺像某種型號,意味着必須有一個主列表可能會限制這一點。我離開了基地嗎? – randcd