Обработка ошибок SQL Server в OUTER APPLY
Я не эксперт по T-SQL, и у меня есть проблема (или, скорее, у меня нет проблемы, но я действительно думаю, что должен), которая, я надеюсь, вы можете пролить свет на то, почему.
У меня есть хранимая процедура (SQL Server 2012), которая, по моему мнению, должна выдавать ошибку, но это не так. Мой гугл-фу подвел меня, и я не нашел ничего, что могло бы указать мне правильное направление. В итоге мы используем следующие таблицы:
**USERS**
UserID int
...
**HolidayYears**
HolidayYearID int
UserID int
...
**HolidayYearUserBalances**
BalanceID int
HolidayYearID int
...
Хранимая процедура создает отчет, в котором отображаются пользователи и их праздничные балансы в текущем праздничном году. Для этого я использую OUTER APPLY:
OUTER APPLY (
SELECT TOP 1
HolidayYearID,
YearStart,
YearEnd
FROM HRMHolidayYears
WHERE YearStart <= GETDATE()
AND
UserID = Users.UserID
ORDER BY YearStart DESC
) hy
Это работает абсолютно нормально, и это именно то, что я хочу. Проблема заключается в следующем:
Вчера эта хранимая процедура была передана клиенту, который запускает старую версию нашего приложения. В этой версии HolidayYear не привязан к Пользователю, вместо этого все пользователи совместно используют один и тот же HolidayYear. Таким образом, таблица HolidayYears не имеет столбца "UserID".
Поэтому я ожидаю, что эта хранимая процедура выдаст ошибку, и если я выполню SELECT
содержится в OUTER APPLY
в изоляции он действительно выдает ожидаемую ошибку (неверное имя столбца 'UserID'
).
На самом деле, когда вы запускаете отчет, строки возвращаются без ошибок, однако поля, относящиеся к балансу пользователя, равны NULL (как и следовало ожидать, если OUTER APPLY
не удалось вернуть записи за праздничный год, который затем JOIN
к HolidayYearUserBalances
Таблица.
Я сделал дикое предположение, что T-SQL подавляет ошибки в OUTER APPLY
заявления. Кто-нибудь может подтвердить или опровергнуть это, или предоставить какую-либо информацию, которая может помочь мне решить эту загадку?
1 ответ
Из соответствующих имен столбцов в подзапросах:
Общее правило заключается в том, что имена столбцов в операторе неявно уточняются таблицей, указанной в предложении FROM на том же уровне. Если столбец не существует в таблице, на которую есть ссылка в предложении FROM подзапроса, он неявно определяется таблицей, на которую ссылается предложение FROM внешнего запроса.
В вашем примере у вас есть подзапрос (OUTER APPLY - красная сельдь), и вы используете неявно определенный столбец UserID
, Согласно приведенному выше правилу, поскольку нет UserID
на том же уровне, внешний запрос UserID
будет неявно использоваться. QED.