2008-12-15 10 views
29

Ist es möglich, Spaltendaten mit der ordinal_position für eine Tabellenspalte auszuwählen? Ich weiß, dass die Verwendung von Ordinalpositionen eine schlechte Übung ist, aber für einen einmaligen Datenimportprozess muss ich in der Lage sein, die Ordinalposition zu verwenden, um die Spaltendaten zu erhalten.Ist es möglich, SQL-Server-Daten mit Spalten-Ordinalposition auszuwählen

So zum Beispiel

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

) 

statt mit

select Col2 from Test 

kann ich schreiben

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

Vielen Dank allen für Zeit, um meine Fragen zu beantworten nehmen. Es sieht so aus, als ob ich versuche, es nicht zu tun. – rams

+0

Ratten. Ich habe gerade diese Frage eingegeben. – MusiGenesis

+0

Große Frage. Ich habe mich gefragt, ob das heute möglich ist. – VISQL

Antwort

2

Ja, Sie dies mit einem paar wirklich hässlichen Hits in die Systemtabellen tun könnten. Sie müssten wahrscheinlich in die Welt der dynamischen SQL fallen.

Ich empfehle diesen Ansatz wirklich, wirklich nicht.

Wenn das hat dich nicht davon abhalten, dann könnte dies Sie (ref) loszuzulegen:

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

können Sie diese Abfrage verwenden

select * from information_schema.columns 

die Ordnungspositionen der Spalten zu erhalten. Wie Michael Haren schrieb, musst du eine dynamische Abfrage erstellen, entweder in Code oder in einem Sproc, an den du die Spaltenpositionen übergibst.

FWIW, das ist pure böse.

Auch Deathofrats hat Recht, Sie können dies nicht wirklich tun, da Sie eine regelmäßige Abfrage w/Spaltennamen basierend auf Position erstellen werden.

+3

Liebte die "pure böse" Bemerkung :) –

0

Ich glaube nicht, dass Sie können. Wie @ Michael Haren gezeigt hat, können Sie Ordinalpositionen in ORDER BY-Klauseln verwenden, aber ich habe sie nie anderswo in SQL Server verwendet.

Ich bin nicht sicher, welches Problem Sie mit Ihrem einmaligen Datenimport haben, dass dies mit - vermutlich einem unglücklichen Spaltennamen helfen würde? Kannst du etwas mehr erklären?

+0

@robsoft - Ich arbeite mit einer DB, die Mapping-Informationen verwendet. Col-Namen werden in einer Mapping-Tabelle gespeichert. Ein Proc mit einer HUGE-Case-Anweisung führt den Import aus und ich versuche, ihn zu verbessern. Die Verwendung von dynamischem SQL hat den Prozess nicht beschleunigt. – rams

+0

ah, ich verstehe. Das ist ein ziemlich interessantes Problem! Ich frage mich, ob es durch dynamisches Erstellen von Ansichten getan werden könnte? Ich wünschte, ich hätte gerade etwas zur Hand, um damit zu spielen! :-) – robsoft

13

Sie würden so etwas wie

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

Danke. Mein erster Versuch bestand darin, dynamisches SQL zu verwenden, das mein Proc im Gegensatz zu dem, was ich erwartet hatte, verlangsamte, was mich dazu brachte, mich zu fragen, ob ich die Spalten-Ordinalpositionsinformationen auf irgendeine Weise verwenden könnte. – rams

+0

ok, das ist alles, woran ich denken kann. –

0

zu tun, habe ich von irgendeiner Weise wissen nicht, diese kurz mit dynamischen SQL zu tun. Vielleicht, wenn Sie ein bisschen mehr Informationen darüber enthalten, warum Sie das Gefühl haben, dass Sie die Ordinalwerte verwenden müssen, kann Ihnen jemand hier Rat geben, wie Sie dieses Problem umgehen können.

EDIT: Ich sehe, dass Sie dies zu einem gewissen Grad in einem anderen Kommentar beantwortet. Können Sie genauere Angaben machen? Die Import-Proc- und/oder Tabellendefinitionen?

-5

Wenn Sie MS SQL 2005 verwenden, können Sie die Funktion ROW_NUMBER verwenden.

SELECT Col1, Col2, ROW_NUMBER() OVER (ORDER BY Col1) FROM Test WHERE ROW_NUMBER() über (ORDER BY Col1) Zwischen @Position UND @Position

Das sollten Sie die gewünschten Ergebnisse erhalten, wenn Ich lese die Frage richtig.

1

Wenn Sie die Anzahl der Spalten wissen, könnte ein Weg sein, die Daten in eine tmp Tabelle mit dieser Anzahl von Spalten zu übertragen, und wählen Sie aus der temporären Tabelle ...

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

insert into @tmp 
select * from Test 

select field2 from @tmp 
8

Wenn Sie die Quantität von Spalten, aber nicht wissen, seinen Namen und Typen, können Sie folgenden Trick verwenden:

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 

Als Ergebnis haben Sie eine Tabelle mit zwei Spalten [C1] und [C2]. Diese Methode ist nicht sehr nützlich, wenn Sie 100 Spalten in Ihrer Tabelle haben, aber es funktioniert gut für Tabellen mit einer kleinen vordefinierten Anzahl von Spalten.

+0

Das ist ein netter Trick, aber was passiert mit dem Ausführungsplan? Sagen wir, ich habe eine Million Zeilen in meiner Tabelle und sage, ich möchte "Top 1000" auswählen. Würde dieser Trick den Server weiterhin den Index verwenden lassen? –

0

Eine Option, die Sie haben Bedingungen verwendet: In Ihrem Beispiel:

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

Schema zu gehen Abfrage verlangsamen fürchte ich ...