2008-12-15 11 views
29

¿Es posible seleccionar datos de columna usando la posición ordinal para una columna de tabla? Sé que usar posiciones ordinales es una mala práctica, pero para un proceso de importación de datos único, necesito poder usar la posición ordinal para obtener los datos de la columna.¿Es posible seleccionar datos del servidor sql usando la posición ordinal de columna

Así, por ejemplo

create table Test(
    Col1 int, 
    Col2 nvarchar(10) 

) 

en lugar de utilizar

select Col2 from Test 

puedo escribir

select "2" from Test -- for illustration purposes only 
+0

Gracias a todos por tomarse el tiempo para responder a mis preguntas. Parece que lo que intento hacer no se puede hacer. – rams

+0

Ratas. Estaba escribiendo esta misma pregunta. – MusiGenesis

+0

Gran pregunta. Me preguntaba si esto era posible hoy. – VISQL

Respuesta

2

Sí, se puede hacer esto con algunos golpes muy feos en las tablas del sistema. Probablemente necesites caer en el mundo del sql dinámico.

Realmente, realmente no recomiendo este enfoque.

Si eso no le impidió, entonces esto podría ayudarle a empezar (ref):

select table_name, column_name, ordinal_position, data_type 
from information_schema.columns 
order by 1,3 
4

Puede utilizar esta consulta

select * from information_schema.columns 

para obtener las posiciones ordinales de las columnas. Al igual que Michael Haren escribió, tendrá que crear una consulta dinámica usando esto, ya sea en código o en un sproc al que le pase las posiciones de las columnas.

FWIW, esto es pura maldad.

Además, deathofrats es correcto, realmente no se puede hacer esto, ya que se creará una consulta regular con nombres de columna en función de la posición.

+3

Me encantó la observación del "mal puro" :) –

0

No creo que puedas. Como mostró @Michael Haren, puede usar posiciones ordinales en cláusulas ORDER BY, pero nunca las he visto en otro lugar de SQL Server.

No estoy seguro de qué problema está teniendo con su importación de datos únicos que esto ayudaría con - ¿presumiblemente algún desafortunado nombre de columna? ¿Puedes explicar un poco más?

+0

@robsoft - Estoy trabajando con un DB que utiliza la información de asignación. Los nombres de los Col se almacenan en una tabla de mapeo. Un proceso con una declaración de caso ENORME ejecuta la importación y estoy tratando de mejorarlo. El uso de SQL dinámico no aceleró el proceso. – rams

+0

ah, ya veo. ¡Es un problema bastante interesante! Me pregunto si se podría hacer creando vistas dinámicamente. ¡Ojalá tuviera algo a mano ahora para jugar! :-) – robsoft

13

Habría que hacer algo como

declare @col1 as varchar(128) 
declare @col2 as varchar(128) 
declare @sq1 as varchar(8000) 

select @col1 = column_name from information_schema.columns where table_name = 'tablename' 
and ordinal_position = @position 

select @col2 = column_name from information_schema.columns where table_name = 'tablename' 
and ordinal_position = @position2 

set @sql = 'select ' + col1 ',' + col2 'from tablename' 

exec(@sql) 
+0

Gracias. Mi primer intento fue utilizar SQL dinámico, que en realidad ralentizó mi proceso al contrario de lo que esperaba, lo que me llevó a preguntarme si podría usar la información de posición ordinal de la columna de cualquier forma. – rams

+0

bien, eso es todo lo que puedo pensar. –

0

Yo no sé de ninguna manera de hacer este corto de uso de SQL dinámico. Tal vez si incluye un poco más de información sobre por qué siente que tiene que usar los valores ordinales, alguien aquí puede darle consejos sobre cómo solucionar ese problema.

EDIT: Veo que ha respondido esto hasta cierto punto en otro comentario. ¿Puedes proporcionar más detalles? ¿El proceso de importación y/o las definiciones de tabla?

-5

Si está utilizando MS SQL 2005 puede usar la función ROW_NUMBER.

SELECT Col1, Col2, ROW_NUMBER() OVER (ORDER BY Col1) DE prueba DONDE ROW_NUMBER() sobre (la orden por el Col1) Entre @Position Y @Position

que deberían obtener los resultados deseados si Estoy leyendo la pregunta correctamente.

1

Si conoce el número de columnas, una forma podría ser la transferencia de los datos en una tabla tmp con ese número de columnas y seleccione de la tabla temporal ...

declare @tmp table(field1 sql_variant, field2 int, field3 sql_variant) 

insert into @tmp 
select * from Test 

select field2 from @tmp 
8

Si conoce la cantidad de columnas, pero no saben sus nombres y tipos, puede utilizar siguiente truco:

select NULL as C1, NULL as C2 where 1 = 0 
-- Returns empty table with predefined column names 
union all 
select * from Test 
-- There should be exactly 2 columns, but names and data type doesn't matter 

Como resultado, tendrá una tabla con 2 columnas [C1] y [C2]. Este método no es muy útil si tiene 100 columnas en su tabla, pero funciona bien para tablas con un pequeño número predefinido de columnas.

+0

Este es un buen truco, pero ¿qué ocurre con el plan de ejecución? Supongamos que tengo un millón de filas en mi tabla y digo que quiero seleccionar 'top 1000'. ¿Este truco permitiría que el servidor use el índice? –

0

Una opción que tienes está utilizando condiciones: En su ejemplo:

SELECT 
    CASE YourColumnNumber 
     WHEN "1" THEN Col1 
     WHEN "2" THEN Col2 
     ELSE "?" 
    END AS Result 
    FROM Test 

ir a consulta esquema se ralentizará me temo ...

Cuestiones relacionadas