Sql 如何从表中的列中选择值,动态使用其他表中的列名(反射)

Sql 如何从表中的列中选择值,动态使用其他表中的列名(反射),sql,sql-server,Sql,Sql Server,我正试图根据另一个类似这样的表中的列id,在具有多个列的表中选择一个值 foo: +-------+--------+--------+--------+ | id | tag | col1 | col2 | +-------+--------+--------+--------+ | 1 | XX | 1 | 2 | +-------+--------+--------+--------+ bar: +-------+--------+-

我正试图根据另一个类似这样的表中的列id,在具有多个列的表中选择一个值

foo:
+-------+--------+--------+--------+
|  id   |  tag   | col1   |  col2  |
+-------+--------+--------+--------+
|   1   |   XX   |    1   |    2   |
+-------+--------+--------+--------+
bar:
+-------+--------+--------+
| id    | field  |  tag   |
+-------+--------+--------+
|   1   |  col1  |   XX   |
+-------+--------+--------+
|   2   |  col2  |   XX   |
+-------+--------+--------+
foobar:
+--------+--------+
|  tag   | value  |
--------++--------+
|   XX   |    1   |
--------++--------+
|   XX   |    2   |
--------++--------+
我想我要寻找的是一种类似反射的机制,在这种机制中,我可以根据属性的名称映射到属性值,而不必事先知道类或表,因为列可以随时间变化,因此生成的表应该是这样的

foo:
+-------+--------+--------+--------+
|  id   |  tag   | col1   |  col2  |
+-------+--------+--------+--------+
|   1   |   XX   |    1   |    2   |
+-------+--------+--------+--------+
bar:
+-------+--------+--------+
| id    | field  |  tag   |
+-------+--------+--------+
|   1   |  col1  |   XX   |
+-------+--------+--------+
|   2   |  col2  |   XX   |
+-------+--------+--------+
foobar:
+--------+--------+
|  tag   | value  |
--------++--------+
|   XX   |    1   |
--------++--------+
|   XX   |    2   |
--------++--------+
我尝试了下面的代码,但是它在两个结果列中都给了我列id,我需要的是特定字段的值,而不是列的名称

declare @SQL nvarchar(max)
declare @Pattern nvarchar(100)

set @Pattern = 'select bar.field, ''foo.[COL_NAME]'' as CurrentValue FROM bar INNER JOIN foo ON foo.[tag] = bar.[tag]'

select @SQL = stuff((select ' union all '+replace(@Pattern, '[COL_NAME]', field)
                 from bar
                 for xml path(''), type).value('.', 'nvarchar(max)'), 1, 11, '')

exec (@SQL)

不要认为用一条SQL语句就可以动态地完成它。但您可以使用动态sql来实现这一点

对于给定的数据集,获得所需结果的最简单方法是使用case语句

select foo.tag, 
case 
    when bar.field = 'col1' then foo.col1
    when bar.field = 'col2' then foo.col2
    else null
end as value
from foo
    inner join bar on foo.tag = bar.tag
只有
当…然后…
部分是动态的,而其余部分是静态的。因此,在
栏上循环
表格以建立动态部分,然后将其全部合并

declare @sql varchar(2000)
set @sql=''
select @sql = @sql +' when bar.field='''+field+''' then foo.' + field
from (select distinct field from bar) sub

--print @sql

set @sql = 'select foo.tag, 
case ' + @sql  + ' 
    else null
end as value
from foo
    inner join bar on foo.tag = bar.tag'

--print @sql

exec(@sql)

这就是动态部分为您所做的…它读取酒吧表中的名称是的,我在提交评论后的一瞬间意识到:)