【问题标题】:Is it possible to select sql server data using column ordinal position是否可以使用列序号位置选择 sql server 数据
【发布时间】:2010-09-26 23:29:43
【问题描述】:

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

例如

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

)

而不是使用

select Col2 from Test

我可以写吗

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

【问题讨论】:

  • 感谢大家花时间回答我的问题。看来我想做的事是做不到的。
  • 老鼠。我只是在输入同样的问题。
  • 好问题。我只是想知道今天这是否可能。

标签: sql sql-server sql-server-2005 tsql ordinals


【解决方案1】:

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

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 列,则此方法不是很有用,但它适用于预定义列数较少的表。

【讨论】:

  • 这是一个不错的技巧,但是执行计划会发生什么?假设我的表中有一百万行,并说我想选择top 1000。这个技巧还会让服务器使用索引吗?
【解决方案2】:

你必须做类似的事情

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,这实际上减慢了我的 proc,这与我的预期相反,这让我想知道我是否可以以任何方式使用列序号位置信息。
【解决方案3】:

你可以使用这个查询

select * from information_schema.columns

获取列的序号位置。就像 Michael Haren 所写的那样,您必须使用它来构建一个动态查询,无论是在代码中还是在将列位置传递给的存储过程中。

FWIW,这纯粹是邪恶的。

另外,deathofrats 是对的,您不能真正做到这一点,因为您将构建一个基于位置的带有列名的常规查询。

【讨论】:

    【解决方案4】:

    是的,您可以通过对系统表进行一些非常难看的命中来做到这一点。您可能需要进入动态 sql 的世界。

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

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

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

    【讨论】:

      【解决方案5】:

      不,据我所知,您不能根据它们的顺序位置选择列。

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

      【讨论】:

        【解决方案6】:

        如果您知道列数,一种方法可能是将数据传输到具有该列数的 tmp 表中,然后从临时表中进行选择...

        declare @tmp table(field1 sql_variant, field2 int, field3 sql_variant)
        
        insert into @tmp
        select * from Test
        
        select field2 from @tmp
        

        【讨论】:

          【解决方案7】:

          您有一个选项是使用条件: 在您的示例中:

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

          恐怕进入模式会减慢查询速度......

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

            • @robsoft - 我正在使用一个使用映射信息的数据库。 Col 名称存储在映射表中。带有 HUGE case 语句的 proc 运行导入,我正在尝试改进它。使用动态 SQL 并没有加快进程。
            • 啊,我明白了。这是一个相当有趣的问题!我想知道是否可以通过动态创建视图来完成?希望我现在有东西可以玩! :-)
            【解决方案9】:

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

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

            【讨论】:

              【解决方案10】:

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

              SELECT Col1, Col2, ROW_NUMBER() OVER(ORDER BY Col1) 从测试 WHERE ROW_NUMBER() Over(Order BY Col1) 在@Position 和 @Position 之间

              如果我正确阅读了问题,那应该会得到你想要的结果。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-01-25
                • 1970-01-01
                • 1970-01-01
                • 2019-10-11
                • 2012-02-26
                • 1970-01-01
                相关资源
                最近更新 更多