使用通配符在数据库中查询SQL Server

时间:2016-11-30 16:09:48

标签: sql sql-server wildcard

我需要构建一个查询,其中条件必须与数据库中的通配符匹配。

举一个例子,它将是最清晰的。

我的列有一个像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 + '%', '~', '_');

2 个答案:

答案 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

答案 1 :(得分:0)

如果你可以收紧通配符上的限制,你可能会有一个战斗机会。我的意思是,如果在持久化数据中显示通配符,则会生成有效排列。然后使用现有查询查询排列。

但是,如果每个通配符都有36个可能的选项,那么这将成为指数级的痛苦。