sql >> Base de Datos >  >> RDS >> Sqlserver

¿Cómo diferenciar los nombres de columna duplicados de diferentes tablas/subconsultas de origen por alias en una declaración de selección de SQL cuando se usa SqlDataReader?

El otro tipo estaba equivocado como sospechaba, así que voy a responder mi propia pregunta.

En SQL Server 2012 (y probablemente en versiones anteriores), descubrí que si llamo a 'set showplan_xml on;' en una consulta arbitraria como:

select * from (select * from Lessons a) a inner join (select * from LessonTypes b) b on a.LessonTypeID = b.ID;

El XML devuelto incluye lo siguiente como su lista de salida de primer nivel/superior, que muestra claramente todas las columnas, y no solo sus tablas de origen, sino también el alias de su subconsulta de origen.

<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>

Entonces, en mi API de base de datos, dado que almaceno todas las cadenas de consultas ordenadamente en un diccionario, puedo realizar un calentamiento de caché al inicio de la aplicación que las ejecuta con xml_showplan activado, analizar las columnas de salida de nivel superior de XML y luego tener un mapeo completo de alias de tabla y nombres de columna a su ordinal de salida.

En realidad, he usado un pequeño truco aquí. En realidad, no es el alias de la subconsulta, sino el alias de la tabla base. Si no incluye un alias en la tabla base, el atributo Alias ​​no está presente en el XML. Sin embargo, es muy simple asegurarse de que cada vez que haga referencia a una tabla real, le dé un alias, eso debería hacer que se envíe al XML, y listo.

Solo para aclarar el punto, los alias se mantienen, incluso cuando se une la tabla a sí misma en una consulta como:

select * from Lessons a, Lessons b, Lessons c , que produce:

<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>

Como puede ver, los alias están intactos y son recuperables.