动态选择列名

时间:2018-04-03 02:48:03

标签: sql sql-server

我在sql编写程序方面有点新意。所以请帮我解决这个问题。

我有一个包含列名的表,我想动态选择列名以从其他列中检索数据。

例如

    Id  colname     Name    Age Salary
     1  Name, Age   Raghu   23  20000
     2  Salary      Raghav  45  30000
     3  Age         Fizal   33  20000

    NewId   colName     Values
       1    Name,Age    Raghu, 23
       2    Salary      20000
       3    Age         33

在#table1中,使用colname我想从其他列(Name,Age,Salary)中提取数据并创建#table2,如上例所示。我想知道实现相同的最佳方法。

1 个答案:

答案 0 :(得分:0)

能做到吗?是。但既然你问最好的方法,我会说这样做一般的事情,并不是一个好的做法。在SQL中重载列很少是个好主意。在这种情况下重载意味着在单个字段中存储多个值,例如[values]包含Raghu, 23。通过将它们作为单独的列留在一起,将它们连接在一起可以获得什么好处?

我的建议是返回所有列,无论Id如何,都取消colname字段。然后你的查询就像这样简单:

select 
    Id, 
    Name,
    Age,
    Salary
from #Data

/* Returns
Id   Name     Age   Salary
---- -------- ----- -----------
1    Raghu    23    20000
2    Raghav   45    30000
3    Fizal    33    20000
*/

是的,您将获得这些行不一定需要的列,例如Salary Id = 1NameAge id = 2,但那是什么?

假设它是一个权利事物,并且您不能只显示所有人的所有列,您可以维护一个授权映射列表(在SQL或您的应用程序中),并只渲染他们有权使用的那些。 / p>

或者如果绝对无法让潜在用户无权通过网络传输数据,您仍然可以在SQL中执行此操作,但只需将其清空您不想返回的列,而不是尝试将所有授权值序列化为单个字段。最终结果是相同的,但这比动态序列化所有数据要容易得多。

执行此操作的过程可能看起来像这样。它仅适用于您提到的三个列,但您可以添加更多参数,或者让它接受字段列表,字段的XML文档或字段的表值参数。我没有采用这些方法,因为他们需要更多的参与实现,但这应该得到了想法

create table #Data
(
    Id int primary key,
    Name nvarchar(50),
    Age int,
    Salary int
)

insert into #Data (Id, Name, Age, Salary)
values 
    (1, 'Raghu', 23, 20000),
    (2, 'Raghav', 45, 30000),
    (3, 'Fizal', 33, 20000)

go

create proc #GetData
    @Id int,
    @ShowName bit,
    @ShowAge bit,
    @ShowSalary bit
as

select
    ID,
    Name = iif(@ShowName = 1, Name, null),
    Age = iif(@ShowAge = 1, Age, null),
    Salary = iif(@ShowSalary = 1, Salary, null)
from #Data
where Id = @Id

然后您将调用此过程:

-- ID: 1
exec #GetData @Id = 1, @ShowName = 1, @ShowAge = 1, @ShowSalary = 0
/*
ID    Name    Age         Salary
----- ------- ----------- -----------
1     Raghu   23          NULL
*/
-- ID: 2
exec #GetData @Id = 2, @ShowName = 0, @ShowAge = 0, @ShowSalary = 1
/*
ID    Name    Age         Salary
----- ------- ----------- -----------
2     NULL    NULL        30000
*/
-- ID: 3
exec #GetData @Id = 3, @ShowName = 0, @ShowAge = 1, @ShowSalary = 0 
/*
ID    Name    Age         Salary
----- ------- ----------- -----------
3     NULL    33          NULL
*/