该表达式如何达到NULL表达式?

时间:2015-03-19 08:55:54

标签: 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并仅插入表中的值?

2 个答案:

答案 0 :(得分:2)

如果您在ID表的vehicle_typ列上没有相应的索引,就会发生这种情况。这是一个较小的查询,表现出同样的问题:

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(checksum(NewID()))%3。只有当{/ 1}} 评估1 1行时,您才会得到一个结果。

如果可能(我不知道你的表格结构)我会首先填充ID中的一列,其中0到20之间的随机数和然后< / em>使用已生成的数字执行此更新。否则,使用当前的查询结构,您始终依赖SQL Server足够聪明,只能为每个外行评估SERVICE_TICKET一次,这可能并不总是如此(因为您已经找到了)出)。

答案 1 :(得分:1)

@Damien_The_Unbeliever解释了您的查询失败的原因。

我的第一个变体不正确,因为我没有完全理解这个问题。

您希望将SERVICE_TICKET中的每一行设置为vehicle_typ的其他随机值。

要修复它,只需按随机数排序,而不是将随机数与ID进行比较。像这样(只要在那里至少有一行,你就不在乎vehicle_typ中有多少行。)

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];

首先我们创建一个公用表表达式,您可以将其视为临时表。对于SERVICE_TICKET中的每一行,我们使用vehicle_typCROSS APPLY中选择一个随机行。然后我们UPDATE选择行的原始表。