Sql server 这个表达式如何到达空表达式?
我尝试使用以下语句使用另一个表中的值随机填充列:Sql server 这个表达式如何到达空表达式?,sql-server,null,Sql Server,Null,我尝试使用以下语句使用另一个表中的值随机填充列: UPDATE dbo.SERVICE_TICKET SET Vehicle_Type = (SELECT TOP 1 [text] FROM dbo.vehicle_typ WHERE id = abs(checksum(NewID()))%21) 它似乎工作正常,但是值NULL被插入到列中。如何去除NULL并仅插入表中的值?如果您的车辆类型表的ID列上没
UPDATE dbo.SERVICE_TICKET
SET Vehicle_Type = (SELECT TOP 1 [text]
FROM dbo.vehicle_typ
WHERE id = abs(checksum(NewID()))%21)
它似乎工作正常,但是值
NULL
被插入到列中。如何去除NULL
并仅插入表中的值?如果您的车辆类型表的ID
列上没有适当的索引,则可能发生这种情况。下面是一个显示相同问题的较小查询:
create table T (ID int null)
insert into T(ID) values (0),(1),(2),(3)
select top 1 * from T where ID = abs(checksum(NewID()))%3
因为T
上没有索引,所以SQL Server会执行表扫描,然后对每一行尝试满足where子句。这意味着,对于每一行,它将重新计算abs(校验和(NewID()))%3
。只有当该表达式对ID为1的行求值时,碰巧生成了1
时,才会得到结果
如果可能的话(我不知道您的表结构),我会首先在SERVICE\u TICKET
中用一个介于0和20之间的随机数填充一列,然后使用已经生成的数字执行此更新。否则,在当前的查询结构中,您总是依赖SQL Server足够聪明,只对每个外部行计算一次abs(checksum(NewID())%21
,这可能并不总是如此(正如您已经发现的那样)。@Damien\u不信者解释了查询失败的原因
我的第一个变体不正确,因为我没有完全理解这个问题
您希望将服务\u TICKET
中的每一行设置为与车辆类型
不同的随机值
要修复它,只需按随机数排序,而不是将随机数与ID
进行比较。这样(只要至少有一行,你就不在乎车辆类型中有多少行)
首先,我们创建一个公共表表达式,您可以将其视为一个临时表。对于SERVICE\u TICKET
中的每一行,我们使用交叉应用
从车辆类型
中随机选取一行。然后我们用所选行更新原始表。这不是mysql
语法,更新问题并更改标记。这不是mysql
语法。请使用sql server
标记。在vehicle\u typ
中是否有包含从0
到20
的所有可能ID的行?如果不是,这就是产生NULL
s的原因。是的,车辆类型包括从0到20的所有可能行-因此这不是NULL的原因。好的,我看到了问题。。。那么,我怎样才能从上面改变我的表达来摆脱这个问题呢?@LKH-我不知道你读到了我的答案的哪个版本-我在底部添加了一个新段落,其中一个建议是我如何尝试解决这个问题。感谢你的回答-我创建了一个聚集索引,空值消失了。然而,现在每个值都是相同的。。。你知道如何让随机不同的值不为NULL吗?我完全按照你描述的复制了表达式。但是,我无法执行它,因为找不到多部分标识符dbo.SERVICE\u TICKET.Vehicle\u Type。此外,“交叉应用”显示为灰色。@LKH,我不明白您为什么会出现错误。如果您尝试简单的从dbo.SERVICE\u TICKET中选择dbo.SERVICE\u TICKET.Vehicle\u Type
是否有效?
WITH
CTE
AS
(
SELECT
dbo.SERVICE_TICKET.Vehicle_Type
CA.[text]
FROM
dbo.SERVICE_TICKET
CROSS APPLY
(
SELECT TOP 1 [text]
FROM dbo.vehicle_typ
ORDER BY NewID()
) AS CA
)
UPDATE CTE
SET Vehicle_Type = [text];