如何在SQL查询中实现不喜欢

时间:2016-04-26 05:20:41

标签: sql sql-server tsql stored-procedures

我有这个示例数据的表UserRule

Ruleid   IsActive    Title      Description    Content     RuleName    priority
 -------------------------------------------------------------------------------        
 100      1        %Test%       %One%          %Reza%      Contain       1
 101      1        Talebi       Ahmad          Zahra       Equal         2
 102      1        %Ali         %Omid          %Kaveh      StartWith     3
 103      1        Samira%      Mina%          Amir%       EndWith       4

对于Contain,Equal,StartWith和EndWith操作,此存储过程有效:

Alter procedure GetRule
    @Title nvarchar(max),
    @Description nvarchar(max),
    @Content nvarchar(max)
as 
begin
     Select top(1) 
         UserRule.*  
     from 
         UserRule 
     where 
         IsActive = 1 
         and @Title like UserRule.Title
         and @Description like UserRule.Description
         and @Content Like UserRule.Content
     Order by 
         UserRule.Priority  ASC

现在,我们希望为RuleName列实现负状态,例如(不包含,不等于,不是startwith而不是endwith)具有相同的存储过程。如何实现不喜欢与喜欢?

3 个答案:

答案 0 :(得分:1)

总的来说,你不能。除%之外,LIKE模式的每个其他部分都是关于单个字符的断言。因此,_匹配任何单个字符。 [...]匹配与[]中表达的字符匹配的任何单个字符。 [^...]匹配与[]中表达的字符不匹配的任何单个字符。

因此,像NOT LIKE 'abc'这样的表达式匹配任何不完全是三个字符长的字符串或任何不完全是abc的三个字符串。使用LIKE模式无法表达简单的事情。例如。你可能认为LIKE '[^a][^b][^c]'是等价的,但一些快速思考会证明不是这样。它不接受长度不正好3个字符的字符串。并且它会拒绝dbe之类的字符串,因为它在第二个位置包含b

您需要重新编写查询以显式处理否定匹配,而不是期望能够编写“等效”LIKE模式。

E.g。假设您的表格中有一个名为NegateMatch的附加列,bit 1where IsActive=1 and ( ( NegateMatch = 0 and @Title like UserRule.Title and @Description like UserRule.Description and @Content Like UserRule.Content ) or ( NegateMatch = 1 and not ( @Title like UserRule.Title and @Description like UserRule.Description and @Content Like UserRule.Content ) ) ) Order by UserRule.Priority ASC 意味着否定匹配,您可以使用以下内容:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container">
    <div class="row">
        <div class="col-xs-12 col-md-6">
            <div>
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ratione ipsam nobis porro, cum eum? Repellat libero deleniti dolorem illum ex officia nostrum error. Vel quaerat, officia ducimus pariatur quas voluptas. 
            </div>
        </div>
        <div class="col-xs-12 col-md-6" id="result"> 
            <table>
                <tr>
                    <td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti modi odio hic sequi, magni saepe accusantium. Officiis delectus corrupti exercitationem vel, quo, nemo blanditiis voluptatibus nihil recusandae, ab voluptatum rerum.</td>
                </tr>
                                <tr>
                    <td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti modi odio hic sequi, magni saepe accusantium. Officiis delectus corrupti exercitationem vel, quo, nemo blanditiis voluptatibus nihil recusandae, ab voluptatum rerum.</td>
                </tr>
                                <tr>
                    <td>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti modi odio hic sequi, magni saepe accusantium. Officiis delectus corrupti exercitationem vel, quo, nemo blanditiis voluptatibus nihil recusandae, ab voluptatum rerum.</td>
                </tr>
            </table>
        </div>
    </div>
</div>

<style>

#result {
    overflow-y:scroll;
    height:100px;
}

</style>

答案 1 :(得分:0)

根据我对你的问题的理解,我建议在存储过程中添加一个参数,比如@IfContains bit = 0,并按如下方式实现存储过程......

Alter procedure GetRule
@Title nvarchar(max),
@IfContains   bit = 0

As
BEGIN

If IfContains = 0 Then
BEGIN
    Select  top(1) UserRule.*  from UserRule where 
    IsActive=1 and  @Title like UserRule.Title
    Order by UserRule.Priority  ASC
END

If IfContains = 1 Then
BEGIN
    Select  top(1) UserRule.*  from UserRule where 
    IsActive=1 and  @Title Not like UserRule.Title
    Order by UserRule.Priority  ASC
END

END

通过这种方式,它不会破坏应用程序中对存储过程的现有调用,如果要在查询的where子句中使用“Not Like”,则可以传递第二个参数。

答案 2 :(得分:0)

在sql server中它会像这样工作,这只是为了表明如何使用

SELECT * FROM GetRule WHERE @Title not LIKE'%'+ REPLACE(UserRule.Title,'^','')+'%'