如何翻转 T-SQL 中的位域?
Posted
技术标签:
【中文标题】如何翻转 T-SQL 中的位域?【英文标题】:How to flip bit fields in T-SQL? 【发布时间】:2009-09-09 03:00:43 【问题描述】:我正在尝试使用更新查询翻转 SQL Server 中的位字段,也就是说,我想将所有 0 变为 1,反之亦然。什么是最优雅的解决方案?
T-SQL 中似乎没有按位 NOT 运算符(除非我遗漏了一些明显的东西),而且我找不到任何其他执行更新的方法。
【问题讨论】:
【参考方案1】:您不需要按位进行 - 只需将其与 1 / true 异或即可。
检查:
select idColumn, bitFieldY, bitFieldY ^ 1 as Toggled
from tableX
更新:
update tableX
set bitFieldY = bitFieldY ^ 1
where ...
MSDN T-SQL Exclusive-OR (^)
【讨论】:
太棒了!谢谢你 - 它就像一个魅力。我显然需要更多地了解如何使用二元运算符 另一篇:blogs.lessthandot.com/index.php/DataMgmt/DBProgramming/… 请记住,bitFieldY ^ 1
将返回 int
,因此如果您需要它再次成为 bit
,CAST
或 CONVERT
将返回到 bit
。
【参考方案2】:
为什么不简单的bitfield = 1 - bitfield
?
【讨论】:
一种巧妙而优雅的方法,特别是对于一次性查询,可读性并不重要。 @Billious 和 GBN 你们都是对的,但我想 Austin 的回复足以理解目标的明确含义。用 1-x 翻转一点会使新手感到困惑,因此不是实现它的正确方法。我也同意做某事的方法不止一种,但如果有推荐的方法,我们应该采用它,这可能比不推荐的方法更快。 对于可以为空的bitfield
,一种方法可能是bitfield = 1 - ISNULL(bitfield,0)
。请参阅文档中的ISNULL。
@UweKeim 就个人而言,我不使用 NULLable 位。从来没有真正需要 3 个状态来处理比特
谢谢,@gbn。我有时在有一个遗留表时会这样做,我稍后会在其中添加一个新的位域列。 (如果有更多的知识,这可能会更优雅地解决)。【参考方案3】:
另一种方法是
DECLARE @thebit bit = 1, @theflipbit bit
SET @theflipbit = ~ @thebit
SELECT @theflipbit
其中“~”表示“NOT”运算符。它很干净,您可以阅读很好的代码。 “否定位”更加简洁,它完全符合“NOT”运算符的设计目的。
【讨论】:
同样的想法,但将 NULLS 变为 true:UPDATE TABLE_NAME SET BIT_FIELD= IIF(BIT_FIELD IS NULL,1,~ BIT_FIELD)【参考方案4】:我很确定大多数 SQL 风格都有按位 NOT,所以我检查了一下,确实有 appear to be one in TSQL。
从文档中,它是字符 ~
。
【讨论】:
SELECT ~MyBitField from MyTable 换句话说,更新 MyTable set MyBitField = ~MyBitField【参考方案5】:UPDATE tblTest SET MyBitField = CASE WHEN MyBitField = 1 THEN 0 ELSE 1 END
这很乏味,但每个人都会明白它在做什么。
编辑:
您可能还需要按照 cmets 中的建议考虑空值。当然取决于你的需求。
UPDATE tblTest SET
MyBitField = CASE
WHEN MyBitField = 1 THEN 0
WHEN MyBitField = 0 THEN 1
ELSE NULL -- or 1 or 0 depending on requirements
END
【讨论】:
这会将 MyBitField 设置为 1,当它以 NULL 开始时。不完全是翻转位。 我认为这是不言而喻的......但我会添加有关处理空值的信息以防万一。 我倾向于同意其他一些人的观点并选择 ~ 或 "^ 1 "。特别是如果这是一次性的事情(看起来更干净)。但是,如果这会持续存在并且可维护性存在问题,那么这个解决方案肯定是最直接的。 在我的例子中,这是一个一次性查询,所以可维护性不是问题,但是,是的,这同样可以很好地工作。我实际上已经编写了一个类似的查询,但无法让 CASE 语句正常工作。我现在意识到这是一个简单的语法错误。哦! 我也喜欢这个。我有时会发现,如果我在代码中遇到一个我不理解的符号,那么很难弄清楚编码器的意图。但这很明显。【参考方案6】:一个简单的按位非运算符 (~) 在 SQL Server 2014 - 12.0.2269.0 中为我工作
在 T-SQL 中的更新子句中 -
Update TableName
SET [bitColumnName] = ~[bitColumnName],
....
WHERE ....
希望对你有帮助
参考 - https://docs.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-not-transact-sql
【讨论】:
【参考方案7】:你试过了吗?
UPDATE mytable SET somecolumn =
CASE WHEN somecolumn = 0 THEN 1
WHEN somecolumn IS NULL THEN NULL
WHEN somecolumn = 1 THEN 0
END
【讨论】:
【参考方案8】:查询 (vb)
x = "select x from table"
更新(vb)
"update table set x=" Not(x*(1))
【讨论】:
即使在 vb 中这也不起作用,问题是针对 t-sql以上是关于如何翻转 T-SQL 中的位域?的主要内容,如果未能解决你的问题,请参考以下文章