在SQL Server中基于条件创建视图

在SQL Server中基于条件创建视图,sql,sql-server,stored-procedures,view,user-defined-functions,Sql,Sql Server,Stored Procedures,View,User Defined Functions,这个问题被问了好几次,但有些事情我想不出来 首先,我需要创建视图(必须是视图),但要根据一个查询的结果 create view as if (select count(oid)...)>1 select1 else select2 我知道这张表格是不允许的。但是我怎样才能完成这样的事情呢?我需要创建几十个这样的视图。因为这些SELECT语句包含空间条件,而且数据库很大,有很多表,所以我需要“最佳”解决方案,否则它将永远查询 我读了一些关于使用存储过程和UD函数的书,但是如何从

这个问题被问了好几次,但有些事情我想不出来

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

create view as
if (select count(oid)...)>1
   select1
else
   select2
我知道这张表格是不允许的。但是我怎样才能完成这样的事情呢?我需要创建几十个这样的视图。因为这些SELECT语句包含空间条件,而且数据库很大,有很多表,所以我需要“最佳”解决方案,否则它将永远查询

我读了一些关于使用存储过程和UD函数的书,但是如何从中创建视图并获得最大性能呢?
我不需要参数,只需要创建由该条件定义的视图的方法。

您可以使用一个视图调用存储过程

create view ConditionalView as
execute sp_ConditionalView 

然后将条件代码放入存储过程。

最理想的解决方案是IF语句。可以说,您尝试做的任何其他事情都是次优的。很可能是极不理想的。所以这排除了一种观点

create view ConditionalView as
execute sp_ConditionalView 
尝试表示条件2选择的查询(这是可能的,但不是一个好主意)的问题是需要将查询编译到特定的执行计划中。没有“有条件”的执行计划,该计划必须适用于所有情况。即使select1和select2可能都有一个最佳的执行计划,但在单个SELECT中表示这两个选项的查询也不会有任何最佳计划。查询可能会以一个暴力计划结束,该计划扫描所有表,忽略所有索引


即使尝试使用基于多语句表值函数的视图进行欺骗也不太可能奏效(至少效率不高)。不要这样做。回到设计板,尝试设计使用数据库的东西,而不是与之抗争。

如果只需要从存储过程创建视图(而不是实际从视图返回数据),则需要使用动态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);
不过,我怀疑它会表现得特别好


为什么它必须是一个视图?存储过程不需要有参数。你有没有研究过case语句?@rhealitycheck,因为我需要在其他软件中将该视图用作源数据集。他只接受表和视图,所以我不能创建表,因为有大量的数据和表。在创建视图时,case能帮我什么忙(当然是出于选择)?您创建了存储过程吗?恐怕无法更改整个设计:/