【问题标题】:Is there an exclusive OR operator in T-SQL?T-SQL 中是否有异或运算符?
【发布时间】:2011-08-25 19:26:13
【问题描述】:

这是我的声明

IF (@UserName IS NULL AND @EditorKey IS NULL) OR (@UserName IS NOT NULL AND @EditorKey IS NOT NULL) BEGIN
    RAISERROR ('One of @UserName, @EditorKey must be non-null.', 15, 0)
    RETURN
END

我想要的是能够做这样的事情:

IF (@UserName IS NOT NULL) XOR (@EditorKey IS NOT NULL) BEGIN
    RAISERROR ('One of @UserName, @EditorKey must be non-null.', 15, 0)
    RETURN
END

对于两个参数来说,这没什么大不了的,但有些 proc 有三个或四个,其中只有一个可以传递,其余的应该为 null。

【问题讨论】:

  • 您的第一个语句(a AND b) OR (NOT a AND NOT b)a EQU b(逻辑等价)的替代,这在逻辑上是XOR 的否定。后者表示,例如,像这样:(a AND NOT b) OR (NOT a AND b) 或像这样:(a OR b) AND (NOT a OR NOT b)
  • T-SQL XOR Operator 的可能重复项

标签: tsql


【解决方案1】:

不是很简洁,但你可以像这样展开逻辑:

WHERE
    (NOT ((@UserName IS NOT NULL) AND (@EditorKey IS NOT NULL))) AND
    ((@UserName IS NOT NULL) OR (@EditorKey IS NOT NULL))

或者使用按位异或运算符(^):

WHERE
    (CASE WHEN (@UserName IS NOT NULL) THEN 1 ELSE 0 END) ^
    (CASE WHEN (@EditorKey IS NOT NULL) THEN 1 ELSE 0 END) = 1

您可以使用类似的方法,其中有三个或四个参数,并且必须有一个值:

WHERE
    (CASE WHEN (@Var1 IS NOT NULL) THEN 1 ELSE 0 END) +
    (CASE WHEN (@Var2 IS NOT NULL) THEN 1 ELSE 0 END) +
    (CASE WHEN (@Var3 IS NOT NULL) THEN 1 ELSE 0 END) +
    (CASE WHEN (@Var4 IS NOT NULL) THEN 1 ELSE 0 END) = 1

【讨论】:

  • 表达式的前半部分本质上是((@UserName IS NULL) OR (@EditorKey IS NULL)),根据De Morgan's laws.
  • @Andriy 同意,我将(@UserName IS NOT NULL) 视为一般情况下的布尔表达式,而不简化任何逻辑。
  • 它不漂亮,但至少可以扩展。
  • 如果没有更好的方法,这有点令人不满意。主要限制似乎是 TSQL 中缺少适当的 bool 数据类型。
【解决方案2】:

作为一个作弊者,你可以这样做:

If @UserName+@EditorKey is null and coalesce(@UserName,@EditorKey) is not null

它更短,但这可能是它唯一的用途。

【讨论】:

    【解决方案3】:

    有一个按位异或,但不一定是你想要的:

    http://msdn.microsoft.com/en-us/library/ms190277.aspx

    在您的特定情况下,我发现像这样重写它更直接:

    IF (@UserName IS NULL) = (@EditorKey IS NULL) BEGIN
    

    【讨论】:

    • 爱它。要将其转化为真正的 XOR,((logical condition) <> (other logical condition)).
    • 如果我错了,请纠正我,但是您的SQL server Boolean数据类型无法比较? “IF (NULL IS NULL) = (NULL IS NULL) PRINT 'COMPARABLE'”产生“'=' 附近的语法错误”
    • @shannon:你不应该在开始/结束之间包装打印吗?
    • @Denis:这肯定是更好的形式,但对于单个操作来说不是必需的。结果是一样的。你可以试一试,如果我错了,可以告诉我吗?此刻我正在写类似的约束。很想使用这种技术并为你投票。
    • Tbh,我只是翻译了我所做的 Postgres,它工作得很好......我偶尔使用检查约束中的构造来使字段互斥。
    猜你喜欢
    • 2013-04-19
    • 1970-01-01
    • 2012-02-08
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 2012-03-18
    • 2019-05-03
    相关资源
    最近更新 更多