和/或基于存储过程中的变量值

和/或基于存储过程中的变量值

问题描述:

我想在存储过程中的条件之间使用AND/OR,并且决定取决于参数值,无论它是0(AND)还是1(OR)和/或基于存储过程中的变量值

任何人都可以帮助我请这个,我想这是一件容易的事情,但我似乎无法弄清楚。谢谢

+0

你能告诉我们你到底想到了什么吗? – 2012-01-02 15:02:33

+0

如果列索引,您可能会更好地为此执行2个单独的查询或动态SQL。 “OR”的最佳计划可能与“AND”的完全不同 – 2012-01-02 15:03:34

最简单的方法(乍一看)将使用动态SQL连接查询字符串,但动态SQL有它的问题。
请参阅The Curse and Blessings of Dynamic SQL的深入解释。

所以我会尽量避免动态SQL,如果您的查询不是太复杂,这没什么大不了的。
最简单的方法就是火取决于参数值的两个不同的查询:

CREATE PROCEDURE spTest 
    @AndOr bit 
AS 
BEGIN 

    if @AndOr = 0 begin 

     select * from YourTable where foo = 1 and bar = 2 

    end 
    else begin 

     select * from YourTable where foo = 1 or bar = 2 

    end 

END 

这当然是一个非常简单的查询的例子。
如果你有大量的查询,或者如果您的查询是非常复杂的,这可能不是最好的解决方案,因为它迫使你复制所有查询......但一如既往,这取决于:-)

具有input parameter您可以使用IF clause来制作不同的selects

If input parameter = 0使AND conditions,否则使OR conditions

我看不到任何特别优雅的方式来做到这一点。所以这里是直接的方法

create function myfun (@parm1 int, @parm2 int, @andor int) returns int 
begin 
if (@andor = 0 AND @parm1 = 99 AND @parm2 = 99) return 1 
else if (@andor = 1 AND (@parm1 = 99 OR @parm2 = 99)) return 1 
return 0 
end 
go 
select dbo.myfun(99,98,0) -- AND condition should return 0 
select dbo.myfun(99,98,1) -- OR condition should return 1 
select dbo.myfun(98,98,0) -- AND condition should return 0 
select dbo.myfun(98,98,1) -- OR condition shoujld return 0 

您可以在CASE语句上实现您的逻辑。事情是这样的:

CREATE PROCEDURE dbo.MySP @OrAnd BIT 
AS 
BEGIN 
    SELECT * 
    FROM MyTable 
    WHERE CASE WHEN Condition1 AND Condition2 AND @OrAnd = 0 THEN 1 
      WHEN (Condition1 OR Condition2) AND @OrAnd = 1 THEN 1 ELSE 0 END = 1 
END 

如果转换简单的条件的布尔结果为数字的人(01),你就可以使用你的参数以下列方式:

(
    (CASE WHEN condition1 THEN 1 ELSE 0 END^@AndOr) 
    & 
    (CASE WHEN condition2 THEN 1 ELSE 0 END^@AndOr) 
)^@AndOr = 1 

这里@AndOr是您的参数,^是Transact-SQL按位独占或运算符,&代表Transact-SQL中的按位,以及CASE表达式用于将布尔结果转换为01

如果@AndOr = 0(这意味着我们想要的条件之间AND),则上面的表达式有效归结为:

case1 & case2 = 1 

因为X XOR 0产量Xcase1case2所以既不单独的值,也没有整个结果&运营商不受^运营商的影响。因此,当@AndOr0时,原始表达式的结果将等于condition1 AND condition2的结果。

现在,如果@AndOr = 1(即OR),然后每^操作者在表达式返回其左操作数的反转值,换句话说,否定左操作数,由于1 XOR 1 = 00 XOR 1 = 1。因此,原来的表达将基本上等同于以下情况:

¬ (¬ case1 & ¬ case2) = 1 

其中¬意味着否定。或者,将其转换回布尔值,这将是这样的:

NOT (NOT condition1 AND NOT condition2) 

De Morgan's laws之一,

(NOT A) AND (NOT B) = NOT (A OR B) 

它应用到上述条件,我们得到:

NOT (NOT condition1 AND NOT condition2) = NOT (NOT (condition1 OR condition2)) = 
= condition1 OR condition2 

因此,当@AndOr1时,我在答案的开头给出的表达式等于condition1 OR condition2。因此,它的工作原理基于@AndOr的值。