Обработка ошибок 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.

Другие вопросы по тегам