Чтобы безопасно назначить переменную, вы должны использовать инструкцию SET-SELECT:
SET @PrimaryContactKey = (SELECT c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey
AND i.invckey = @tmp_key)
Убедитесь, что у вас есть как начальная, так и конечная скобка!
Причина, по которой версия SET-SELECT является самым безопасным способом задания переменной, двояка.
1. SELECT возвращает несколько сообщений
Что произойдет, если следующий выбор приведет к нескольким сообщениям?
SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey
AND i.invckey = @tmp_key
@PrimaryContactKey
будет присвоено значение из последнего сообщения в результате.
Фактически @PrimaryContactKey
будет присвоено одно значение на сообщение в результате, поэтому оно будет содержать значение последнего сообщения, которое обрабатывает команда SELECT.
Какой пост является «последним», определяется любыми кластеризованными индексами или, если кластерный индекс не используется или первичный ключ кластеризован, «последний» пост будет последним добавленным постом. Это поведение может в худшем случае изменяться каждый раз, когда изменяется индексирование таблицы.
С помощью инструкции SET-SELECT ваша переменная будет установлена на null
.
2. SELECT не возвращает сообщений
Что происходит при использовании второй версии кода, если ваш выбор вообще не возвращает результат?
В противоположность тому, что вы можете поверить, значение переменной не будет нулевым - оно сохранит это предыдущее значение!
Это потому, что, как указано выше, SQL будет присваивать значение переменной один раз за сообщение - это означает, что он ничего не будет делать с переменной, если результат не содержит сообщений. Таким образом, переменная по-прежнему будет иметь значение, которое она имела до того, как вы запустили оператор.
С оператором SET-SELECT значение будет null
.
См. Также: SET против SELECT при назначении переменных?