首页 > 解决方案 > SQL:选择要从存储过程中返回的不同列

问题描述

假设我有一个mytable包含几列的表(这并不完全正确,请参阅编辑):

mytable
id    data        description          created_at      viewed_times
1      10        'help wanted'      '20180101 04:23'       45
2      20    'customer registered'  '20180504 03:12'        1
...

我创建了一个从该表返回数据的存储过程。问题是有时我需要它只返回iddata列,有时我需要额外的信息,比如descriptioncreated_at

我的想法是创建三个虚拟变量@display_description, @display_created_date, @display_viewed_times。当虚拟变量等于 1 时,我显示相应的列。例如,对于命令

exec my_procedure @display_description = 1

我期望输出

id    data        description        
1      10        'help wanted'      
2      20    'customer registered'  
...

我如何在程序中实现它是:

if @display_description = 1
    select id, data, description from mytable
else 
    select id, data from mytable

问题是,如果我想要 3 个开关(每列一个),我必须在我的if语句中写 8 个条件。(我的select语句比较复杂。另外,有些列如viewed_times要显示,还得计算出来。所以写了很多if语句,查询起来很笨拙,我想避免这种情况)

有没有一种简单的方法可以根据开关选择列?如果不是,您会推荐什么方法从存储过程中返回不同数量的列?

编辑:对不起,我很遗憾该表mytable已经存在所有列。事实并非如此,某些列必须在显示之前进行计算。例如,列viewed_times不存在。要显示它,我需要执行以下操作:

if @display_description = 1
    ~ several selects to calculate the column viewed_times ~
    select id, data, description from mytable join table in which I just calculated the viewed_times column
else 
    select id, data from mytable

计算这些列非常耗时,我只想在需要显示这些列时才这样做。

这就是为什么动态 SQL 可能不起作用的原因

更新:我接受了动态 SQL 的答案,但我所做的是:

if @display_viewed_times = 1
begin   
    ~ calculate column viewed_times ~
    update my_table 
    ~ add column viewed_times to the table my_table ~
end

对于每个可选列。然后我使用返回表

select * from my_table

这给了我不同数量的列,具体取决于开关

标签: sqlsql-serverstored-proceduresdynamic-columns

解决方案


我会将存储过程更改为表值函数并修改外部“选择来源”。

例如:

if($value1 === 1)
  $sql = "SELECT c1, c2 FROM dbo.my_udf";
elseif($value1 ===2)
  $sql = "SELECT c1, c3, c4 FROM dbo.my_udf";

推荐阅读