根据SQL Server中的条件创建视图

时间:2014-10-13 20:03:21

标签: sql sql-server stored-procedures view user-defined-functions

这个问题被多次询问,但我无法弄清楚一些事情。

首先,我需要创建视图(必须是视图),但根据一个查询的结果。

create view as
if (select count(oid)...)>1
   select1
else
   select2

我知道不允许使用此表单。但是我怎么能做到这样的事呢?我需要创建几十个像这样的视图。因为这些SELECT语句包含空间条件,并且数据库很大并且有很多表,所以我需要最优化的'解决方案,或者它将永远查询。

我读过有关使用存储过程和UD函数的内容,但是如何从中创建视图并获得最大性能? 我不需要参数,只是创建由这种条件定义的视图。

3 个答案:

答案 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);

我怀疑它会表现得特别好,不过

Example SQLFiddle