是否可以使用列序号选择sql server数据

问题描述:

是否可以使用表列的ordinal_position选择列数据?我知道使用序数位置是一种不好的做法,但对于一次性数据导入过程,我需要能够使用序数位置来获取列数据。是否可以使用列序号选择sql server数据

因此,例如

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

) 

,而不是使用

select Col2 from Test 

可我写

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

感谢大家抽出时间来回答我的问题。看起来我想要做的事情是无法完成的。 – rams 2008-12-15 16:01:18

+0

大鼠。我只是在输入同样的问题。 – MusiGenesis 2008-12-18 00:58:08

+0

伟大的问题。我只是想知道今天这是否可能。 – VISQL 2013-02-01 00:01:07

是的,你可以用一些非常丑陋的命中进入系统表做到这一点。你可能需要陷入动态sql的世界。

我真的,真的不推荐这种方法。

如果这并没有阻止你,那么这可能让你开始(ref):

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

不,你不能根据自己的序号位置选择列,据我所知。

在查看事务SQL参考时,没有任何建议可以 (http://msdn.microsoft.com/en-us/library/ms176104(SQL.90).aspx)。

您可以使用此查询

select * from information_schema.columns 

获得列的序号位置。就像Michael Haren所写的那样,你必须使用这个动态查询来建立一个动态查询,无论是在代码中还是在你传递列位置的sproc中。

FWIW,这是纯粹的邪恶。

此外,deathofrats是正确的,你不能这样做,因为你会建立一个基于位置的列名定期查询。

+3

喜欢“纯粹的邪恶”言论:) – 2010-08-24 19:36:13

我不认为你可以。正如@Michael Haren所示,您可以在ORDER BY子句中使用序数位置,但是我从未在SQL Server的其他地方看到过它们。

我不确定你的一次性数据导入有什么问题,这将有助于 - 大概是一些不幸的列名?你能多解释一下吗?

+0

@robsoft - 我正在使用一个使用映射信息的数据库。 Col名称存储在映射表中。具有巨大case语句的proc会运行import,并且我正在尝试改进它。使用动态SQL并没有加速这个过程。 – rams 2008-12-15 14:43:41

你不得不这样做

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) 

我不知道有什么办法做到这一点短期使用动态SQL的。也许如果你包含更多关于为什么你觉得你必须使用序数值的信息,那么这里的某个人可以给你如何解决这个问题的建议。

编辑:我看到你在另一个评论中回答了这个问题。你能提供更多细节吗?导入过程和/或表定义?

如果您使用MS SQL 2005,则可以使用ROW_NUMBER函数。

SELECT Col1中,col2的,ROW_NUMBER()OVER(ORDER BY Col1中) 测试从 WHERE ROW_NUMBER()OVER(ORDER BY Col1中)之间@Position和@Position

,应该让你期望的结果,如果我正确地阅读了这个问题。

如果你知道的列数,一个方法可能是将数据与列数转移到tmp目录表,并从临时表中选择...

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

insert into @tmp 
select * from Test 

select field2 from @tmp 

如果你知道的数量列,但不知道它的名称和类型,可以使用以下技巧:

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 

其结果是,你将有2列[C1]及[C2]表。 如果表格中有100列,此方法并不是非常有用,但对于预定义列数较少的表格,此方法效果很好。

你有一个选择是使用条件: 在您的例子:

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

要架构将降低查询恐怕......