假设我有一个包含多列的表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可能无法工作的原因
更新:我接受了Dynamic 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
这给了我不同的列数
答案 0 :(得分:1)
一种方法是使用动态SQL。这是伪SQL,因为这里没有信息来获得完整答案。它也未经测试,因为我没有太多/任何数据可以对此进行真正的测试。
--Your input parameters
DECLARE @description bit, @createdate bit, @viewedtimes bit /*...etc...*/;
--Now the SP
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ' +
STUFF(CONCAT(N','+ NCHAR(10) + N' ' + CASE WHEN @description = 1 THEN QUOTENAME(N'description') END,
N','+ NCHAR(10) + N' ' + CASE WHEN @createdate = 1 THEN QUOTENAME(N'created_at') END,
N','+ NCHAR(10) + N' ' + CASE WHEN @viewedtimes = 1 THEN QUOTENAME(N'viewed_times') END),1,9,N'') + NCHAR(10) +
N'FROM YourTable' + NCHAR(10) +
N'WHERE...;';
PRINT @SQL; --your best debugging friend.
EXEC sp_executesql @SQL /*N'@someParam int', @someParam = @inParam*/;
使用Dyanmic SQL时,请确保正确设置查询的参数。 不要连接字符串!
例如,正确的格式应为N'WHERE yourColumn = @yourParam AND OtherColumn = @otherParam'
,然后在@yourParam
中提供@otherParam
和sp_executesql
的值(正如我在评论中已演示的那样)。
请勿执行以下操作: N'WHERE yourColumn = ''' + @myParam + N''' AND otherColumn = ' + CONVERT(varchar(5),@secondParam)
。这将对SQL注入开放(不是您的朋友)。
答案 1 :(得分:1)
我将存储过程更改为表值函数,并修改外部的“ select from”。
例如:
<div class="header">
</div>
please comment the above code technical -> views -> internal_layout
after call to internal_layout like this
<t t-call="web.internal_layout">
<t t-foreach="docs" t-as="o">
<div class="page" style="font-family: 'helvetica'; font-size: 8pt;">
<div class="header">