2008-12-15 4 views
29

Est-il possible de sélectionner les données de la colonne à l'aide du ordinal_position pour une colonne de table? Je sais à l'aide des positions ordinales est une mauvaise pratique, mais pour un processus d'importation de données unique je dois être en mesure d'utiliser la position ordinale pour obtenir les données de la colonne.Est-il possible de sélectionner les données du serveur SQL en utilisant la position ordinale de la colonne

Ainsi, par exemple

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

) 

au lieu d'utiliser

select Col2 from Test 

que je peux écrire

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

Merci tout le monde pour prendre le temps de répondre à mes questions. Il semble que ce que j'essaie de faire ne peut pas être fait. – rams

+0

Rats. Je tapais juste la même question. – MusiGenesis

+0

Bonne question. Je me demandais juste si c'était possible aujourd'hui. – VISQL

Répondre

2

Oui, vous pouvez le faire avec quelques coups vraiment laids dans les tables système. Vous auriez probablement besoin de tomber dans le monde de SQL dynamique.

Je ne recommande vraiment pas cette approche.

Si cela ne vous dissuade, cela pourrait vous aider à démarrer (ref):

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

Vous pouvez utiliser cette requête

select * from information_schema.columns 

pour obtenir les positions ordinales des colonnes. Comme Michael Haren a écrit, vous devrez construire une requête dynamique en utilisant ce, que ce soit dans le code ou dans un sproc que vous passez les positions de colonne à.

FWIW, c'est du mal pur. En outre, deathofrats a raison, vous ne pouvez pas vraiment le faire, puisque vous créerez une requête régulière avec des noms de colonne en fonction de la position.

+3

J'ai adoré la remarque "pure mal" :) –

0

Je ne pense pas que vous pouvez. Comme montré Haren @ Michael, vous pouvez utiliser des positions ordinales dans les clauses ORDER BY mais je ne l'avez jamais vu les utiliser ailleurs dans SQL Server.

Je ne suis pas sûr du problème que vous avez avec votre importation de données ponctuelle que cela aiderait avec - vraisemblablement un nom de colonne malheureux? Pouvez-vous expliquer un peu plus?

+0

@robsoft - Je travaille avec une base de données qui utilise les informations de mappage. Les noms de colonnes sont stockés dans une table de mappage. Un proc avec une instruction HUGE casse l'importation et j'essaye de l'améliorer. L'utilisation de SQL dynamique n'a pas accéléré le processus. – rams

+0

ah, je vois. C'est un problème assez intéressant! Je me demande si cela pourrait être fait en créant des vues dynamiquement? Souhaite que j'avais quelque chose à la main en ce moment pour jouer avec! :-) – robsoft

13

Il faudrait faire quelque chose comme

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

Merci. Ma première tentative a été d'utiliser le SQL dynamique qui a ralenti mon processus contrairement à ce que j'espérais, ce qui m'a amené à me demander si je pouvais utiliser la colonne ordinal position info de quelle façon. – rams

+0

ok, c'est tout ce que je peux penser. –

0

Je ne connais aucune façon de le faire à court d'utiliser SQL dynamique. Peut-être que si vous incluez un peu plus d'informations sur la raison pour laquelle vous sentez que vous devez utiliser les valeurs ordinales quelqu'un ici peut vous donner des conseils sur la façon de contourner ce problème.

EDIT: Je vois que vous avez répondu à un certain degré dans un autre commentaire. Pouvez-vous fournir plus de détails? Les procédures d'importation et/ou les définitions de tables?

-5

Si vous utilisez MS SQL 2005, vous pouvez utiliser la fonction ROW_NUMBER.

SELECT Col1, Col2, ROW_NUMBER() OVER (ORDER BY Col1) DE test OU ROW_NUMBER() Plus (ORDER BY Col1) Entre @Position ET @Position

Cela devrait vous obtenir les résultats souhaités si Je lis la question correctement.

1

Si vous connaissez le nombre de colonnes, d'une façon peut-être de transférer les données dans une table tmp avec ce nombre de colonnes et sélectionnez la table temp ...

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

insert into @tmp 
select * from Test 

select field2 from @tmp 
8

Si vous connaissez la quantité de colonnes, mais ne savent pas ses noms et types, vous pouvez utiliser suivant astuce:

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 

en conséquence, vous aurez une table avec 2 colonnes [C1] et [C2]. Cette méthode n'est pas très utile si vous avez 100 colonnes dans votre table, mais cela fonctionne bien pour les tables avec un petit nombre prédéfini de colonnes.

+0

C'est une bonne astuce, mais qu'advient-il du plan d'exécution? Dire que j'ai un million de lignes dans ma table, et dire que je veux sélectionner «top 1000». Cette astuce permettrait-elle encore au serveur d'utiliser l'index? –

0

Une option que vous avez utilise des conditions: Dans votre exemple:

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

Aller au schéma interrogera lent j'ai peur ...

Questions connexes