我需要在名为FamName
的表中更新一个名为Episode
的字段,其中包含来自另一个名为Surnames
的表的随机生成的日语名称,该表有一列名为Surname
。
要做到这一点,我首先在ID
表中添加了NONCLUSTERED INDEX
字段和Surnames
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
循环来执行此更新,但我想要一种简洁的方法来执行此操作,并找出在这种特殊情况下我做错了什么。
答案 0 :(得分: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
添加为新列。
您不再需要加入提示。我刚刚测试过这个在我的特定测试用例中有效,尽管我不确定这是否可以保证工作。