ВНУТРЕННЯЯ ПЕТЛЯ СОЕДИНЯЕТСЯ
Мне нужно обновить поле с именем 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
Цикл, чтобы выполнить это обновление, но я хочу краткий способ сделать это и выяснить, что я делаю неправильно в данном конкретном случае.
1 ответ
Вы не можете (надежно) повлиять на результаты запроса с помощью подсказок по соединению. Это подсказки производительности, а не семантические подсказки. Вы пытаетесь положиться на неопределенное поведение.
Перемещение вычисления случайного числа из условия соединения в один из источников соединения предотвращает обработку выражения как константы:
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
как новый столбец.
Вам больше не нужны подсказки о присоединении. Я только что проверил, что это работает в моем конкретном тестовом примере, хотя я не уверен, гарантированно ли это работает.