AND / OR基于存储过程中的变量值

时间:2012-01-02 14:47:48

标签: sql-server stored-procedures

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

任何人都可以帮我这个,我想这是一件容易的事,但我似乎无法弄明白。感谢

5 个答案:

答案 0 :(得分:4)

最简单的方法(乍一看)是使用动态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

这当然是一个非常简单的查询示例 如果您有很多查询,或者您的查询非常复杂,这可能不是最好的解决方案,因为它会强制您复制所有查询...但一如既往,它取决于: - )

答案 1 :(得分:3)

您可以在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

答案 2 :(得分:2)

如果您将简单条件的布尔结果转换为数字(01),您将能够以下列方式使用您的参数:

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

此处@AndOr是您的参数,^是Transact-SQL按位异或运算符,&代表按位 AND 在Transact-SQL中,CASE表达式用于将布尔结果转换为01

如果@AndOr = 0(这意味着我们希望条件之间有AND),上面的表达式可以归结为:

case1 & case2 = 1

因为X XOR 0会产生X,因此case1case2的单个值以及&运算符的整个结果都不会受{ {1}}运营商。因此,当^@AndOr时,原始表达式的结果将等同于0的结果。

现在,如果condition1 AND condition2(即@AndOr = 1),那么表达式中的每个OR运算符都会返回其左操作数的反转值,换句话说,否定左操作数,因为^1 XOR 1 = 0。因此,原始表达式基本上等同于以下内容:

0 XOR 1 = 1

其中¬ (¬ case1 & ¬ case2) = 1 表示否定。或者,将其转换回布尔值,就是这样:

¬

根据De Morgan's laws之一,

NOT (NOT condition1 AND NOT condition2)

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

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

因此,当NOT (NOT condition1 AND NOT condition2) = NOT (NOT (condition1 OR condition2)) = = condition1 OR condition2 @AndOr时,我的答案开头给出的表达式相当于1。因此,它的工作方式与预期的condition1 OR condition2

相同

答案 3 :(得分:0)

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

If input parameter = 0制作AND conditions,否则制作OR conditions

答案 4 :(得分:0)

我看不出任何特别优雅的方式。所以这是直截了当的方法

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