2016-11-30 54 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