【发布时间】:2018-06-22 10:01:36
【问题描述】:
假设我有一个表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
...
我创建了一个从该表返回数据的存储过程。问题是有时我需要它只返回id 和data 列,有时我需要其他信息,例如description、created_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
这给了我不同数量的列,具体取决于开关
【问题讨论】:
-
可以使用动态查询。也谷歌厨房水槽
-
为什么不直接使用
select . . . from?存储过程能给你带来什么价值? -
根据传递的参数返回不同结果集形状的存储过程是有缺陷的界面设计,恕我直言。
-
我必须同意@DanGuzman。将每个排列写成一个单独的过程,然后让调用应用程序决定调用哪一个。
-
@EricBrandt 在这种情况下,我将不得不使用基本相同的代码编写 8 个不同的程序(包括和不包括每一列)。还是我误会了?
标签: sql sql-server stored-procedures dynamic-columns