如何在SQL Server 2008中生成随机布尔值?

18

我正在为某种大学编写一个数据库,其中有一个名为

Contact_Assign

的表格,其参数如下:

Is_Instructor       UD_BOOLEAN NOT NULL,
Is_TeacherAssistant UD_BOOLEAN NOT NULL,
Is_Student          UD_BOOLEAN NOT NULL,
Registration_ID     UD_ID      NOT NULL,
Contact_ID          UD_ID      NOT NULL,

现在我想要在这个表中插入虚拟数据,但我不知道如何为布尔参数做到这一点。

PS. UD_BOOLEAN 是什么

CREATE TYPE UD_BOOLEAN FROM BIT

有任何想法吗?


2
强烈建议只使用BIT。如果你以后决定更改名称、更改底层类型或在NULL / NOT NULL之间进行更改,UD_BOOLEAN除外-会有大量的麻烦吗?您曾经试过在别名类型已经深入到所有对象中之后更改任何关于它的内容吗?现在这似乎是一个聪明的选择,但是从艰难的经历中学习过后,我可以向您保证这不是一个明智的选择。 - Aaron Bertrand
我同意@AaronBertrand的观点。CLR UDTs可能非常有用(尽管一旦部署后更新仍然非常麻烦),但是SQL UDTs真的没什么用。请参阅T-SQL UDTs. (Huh!) What are they good for?以了解更多讨论。 - Martin Smith
此外,不良习惯:使用别名类型 - 那里也有很多好的评论。 - Aaron Bertrand
4个回答

31

您可以使用

CRYPT_GEN_RANDOM(1) % 2

RAND 相比,它在密码学上更强大(您可能不关心),而且如果插入多行,则会为每一行重新评估。
DECLARE @T TABLE(
  B1 BIT,
  B2 BIT);

INSERT INTO @T
SELECT TOP 10 CRYPT_GEN_RANDOM(1)%2,
              CAST(ROUND(RAND(), 0) AS BIT)
FROM   master..spt_values

SELECT *
FROM   @T 

会在第二列的所有行中给出相同的值。

1
+1 这是正确的答案,与 RAND() 无关。 - Aaron Bertrand

11
如果您只需要生成一行,您可以使用如下简单的方式:
SELECT CAST(ROUND(RAND(),0) AS BIT)

然而,如果您正在生成多个行,则RAND()将对每一行求值得到相同的值,请参阅Martin Smith的答案


1
哎呀,不好了。SELECT TOP (1000) CAST(ROUND(RAND(),0) AS BIT) FROM sys.all_columns; 这看起来对我来说并不是很随机。为什么呢?因为 RAND() 只会被评估一次,作为 1 或 0,并且该值在每一行中都保持不变。这只有在逐行生成每一行时才有任何可能工作 - 而你也不应该这样做。 - Aaron Bertrand
3
我本来想删除这个回答,因为它存在这个原因。后来我想了想,意识到这是一个不好的解决方案。可惜它已经被接受了,而不是@MartinSmith的答案。 - Jamiec
感谢 @AaronBertrand。 - Jamiec
您还可以通过以下方式使此解决方案适用于多行:CAST(ROUND(RAND(CHECKSUM(NEWID())),0) AS BIT) - rwblackburn

5
如果您希望第二列使用不同的值,可以使用newid()。以下是一个示例:
select cast((case when left(newid(), 1) between '0' and '7' then 1 else 0 end) as bit)

只有在单个语句中插入多行时,才需要使用newid()


3

另一个使用 NEWID() 的解决方案:

最初的回答。

select ABS(CHECKSUM(NEWID())) % 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接