2

我需要更新一个名为FamName的表中调用的字段,该表Episode使用随机生成的日耳曼语名称来自另一个名为的表Surnames,该表有一个名为Surname.

为此,我首先在表格中添加了一个ID字段NONCLUSTERED INDEXSurnames

ALTER TABLE Surnames 
ADD ID INT NOT NULL IDENTITY(1, 1);
GO
CREATE UNIQUE NONCLUSTERED INDEX idx ON Surnames(ID);
GO

然后我尝试通过更新我的Episode

UPDATE E  
SET E.FamName = S.Surnames 
FROM Episode AS E 
INNER LOOP JOIN Surnames AS S 
    ON S.ID = (1 + ABS(CRYPT_GEN_RANDOM(8) % (SELECT COUNT(*) FROM Surnames)));
GO

我试图使用LOOP连接提示强制查询“循环”。当然,如果我不强制优化器循环(使用LOOP),我将为所有行获得相同的德语名称。但是,这个查询奇怪地返回了零行受影响。

为什么这会返回零受影响的行,如何修改它才能工作?


请注意,我可以使用WHILE循环来执行此更新,但我想要一种简洁的方式来执行此操作,并找出在这种特殊情况下我做错了什么。

4

1 回答 1

3

您不能(可靠地)使用连接提示影响查询结果。它们是性能提示,而不是语义提示。您尝试依赖未定义的行为。

将随机数计算从连接条件移到连接源之一可防止将表达式视为常量:

UPDATE E  
SET E.FamName = S.Surnames 
FROM (
 SELECT *, (1 + ABS(CRYPT_GEN_RANDOM(8) % (SELECT COUNT(*) FROM Surnames))) AS SurnameID
 FROM Episode AS E 
) E
INNER LOOP JOIN Surnames AS S ON S.ID = E.SurnameID

派生表E将计算结果添加SurnameID为新列。

您不再需要加入提示。我刚刚测试了这在我的特定测试用例中是否有效,尽管我不确定这是否可以保证有效。

于 2013-11-29T12:55:02.743 回答