正如我所怀疑的那样,另一个人是错的,所以我要回答我自己的问题。
在 SQL Server 2012(可能还有更早的版本)中,我发现如果我调用 'set showplan_xml on;' 在任意查询上,例如:
select * from (select * from Lessons a) a inner join (select * from LessonTypes b) b on a.LessonTypeID = b.ID;
返回的 XML 包括以下内容作为其第一级/顶级 OutputList,它清楚地显示了所有列,不仅显示了它们的源表,还显示了它们的源子查询的别名。
<OutputList>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="ID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Name"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Description"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Enabled"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="LessonTypeID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="ID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="Name"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="Description"/>
</OutputList>
因此,在我的数据库 API 中,由于我将所有查询字符串整齐地存储在字典中,我实际上可以在应用程序启动时执行缓存预热,在 xml_showplan 上运行它们,解析 XML 顶级输出列,然后具有表别名和列名与其输出序号的完整映射。
实际上,我在这里使用了一个小技巧。它实际上不是子查询的别名,而是基表的别名。如果您未在基表中包含别名,则 XML 中不存在 Alias 属性。但是,确保每次引用实际表时都给它一个别名是非常简单的,这应该会导致它输出到 XML,然后就可以了。
只是为了说明这一点,即使在查询中将表连接到自身时,别名也会保持不变,例如:
select * from Lessons a, Lessons b, Lessons c
,产生:
<OutputList>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="ID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Name"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Description"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Enabled"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="LessonTypeID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="ID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Name"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Description"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Enabled"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="LessonTypeID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="ID"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Name"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Description"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Enabled"/>
<ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="LessonTypeID"/>
</OutputList>
如您所见,别名实际上是完整且可检索的。