这个问题被多次询问,但我无法弄清楚一些事情。
首先,我需要创建视图(必须是视图),但根据一个查询的结果。
create view as
if (select count(oid)...)>1
select1
else
select2
我知道不允许使用此表单。但是我怎么能做到这样的事呢?我需要创建几十个像这样的视图。因为这些SELECT语句包含空间条件,并且数据库很大并且有很多表,所以我需要最优化的'解决方案,或者它将永远查询。
我读过有关使用存储过程和UD函数的内容,但是如何从中创建视图并获得最大性能? 我不需要参数,只是创建由这种条件定义的视图。
答案 0 :(得分:0)
您可以让视图调用存储过程。
create view ConditionalView as
execute sp_ConditionalView
然后在条件代码中加入存储过程。
答案 1 :(得分:0)
“最优解决方案”是IF语句。你试图做的任何其他事情都可能是次优的。很可能非常不理想。所以这排除了一个观点。
尝试表达条件2选择的查询的问题(可能做,但是一个坏主意)是需要将查询编译成特定的执行计划。没有“条件”执行计划,该计划必须适用于所有情况。即使可能select1和select2 每个都有一个最佳执行计划,但在单个SELECT中表达它们的查询也不会有任何最佳计划。查询可能会以扫描所有表的暴力计划结束,忽略所有索引。
即使尝试使用基于多语句表值函数的视图作弊也不太可能起作用(至少不能有效)。只是不要这样做。回到你的设计板,尝试设计一些使用你数据库的东西,而不是与它斗争。
答案 2 :(得分:0)
如果您只需要从存储过程创建视图(而不是从视图中实际返回数据),则需要使用动态SQL:
create proc dbo.makeview as
if (select count(old) > 1 from somthing)
begin
exec sp_executesql N'create view dbo.view1 as select x from y';
end
else
begin
exec sp_executesql N'create view dbo.view1 as select a from b';
end;
当然,这样做,如果条件发生变化,观点就不会改变。您可以管理一些事情,以便在条件发生其他变化时重新创建视图。
要更加动态地执行此操作,并且如果select1和select2具有相同的输出列,则可以使用类似
的内容create view dbo.view1 as
with x as (
select
case when count(old) > 0 then 0 else 1 end cond
from
something
), y as (
select
0 as disc,
rest_of_select1
union all
select
1,
rest_of_select2
) select
col1,
col2
from
y
inner join
x
on x.cond = y.disc
option
(recompile);
我怀疑它会表现得特别好,不过