0

我不是 T-SQL 方面的专家,我遇到了一个问题(或者更确切地说,我没有问题,但我真的认为我应该),希望您能解释一下原因。

我有一个存储过程(SQL Server 2012),我认为它应该给我一个错误 - 但它没有。我的 google-fu 让我失望了,我没有发现任何东西可以为我指明正确的方向。总之,我们使用以下表格:

**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未能返回假期年的记录,您会期望,然后将其返回JOINHolidayYearUserBalances表中。

我做了一个疯狂的假设,即 T-SQL 会抑制OUTER APPLY语句中的错误。任何人都可以确认或否认这一点,或提供任何可能帮助我解决这个难题的信息吗?

4

1 回答 1

1

子查询中的限定列名

一般规则是语句中的列名由同一级别的 FROM 子句中引用的表隐式限定。如果子查询的 FROM 子句中引用的表中不存在列,则外部查询的 FROM 子句中引用的表隐式限定该列。

在您的示例中,您有一个子查询( OUTER APPLY 是一条红鲱鱼),并且您使用了隐式限定的 column UserID。根据上面引用的规则,由于没有UserID同级,因此UserID将隐式使用外部查询。QED。

于 2015-05-06T11:30:24.393 回答