存储过程,并从两个几乎相同的视图中选择

Posted

技术标签:

【中文标题】存储过程,并从两个几乎相同的视图中选择【英文标题】:Stored procedure, and select from two almost identical views 【发布时间】:2012-07-24 07:50:31 【问题描述】:

我有两个视图返回相同的列,但不同的行。

我正在创建一个使用这些视图的存储过程。存储过程很大,并且跨列搜索匹配的行。

现在,我的愿望是:如果我收到一个值为 0 的位参数,那么我应该从一个视图中获取信息,如果参数为 1,那么我应该从另一个视图中获取信息。

我知道动态 SQL 是个坏主意,而且我正在使用的存储过程已经相当复杂。将其重新创建为动态不是一种选择。

我也读到过不可能做到这一点:

select * from @table

因为表名应该是静态的,而不是传递给 ex。通过代码存储过程。

我想要完成的是这样的:

SELECT TOP(@top) subtaskid,activityid FROM 
(CASE WHEN @allProjects=1 THEN view_project_all ELSE view_project_mine) v

但是我收到错误消息说“关键字'CASE'附近的语法不正确。我意识到这个问题与动态sql密切相关,并且***中的变量views\tables问题,但是我认为因为我的两个表实际上是在存储过程中,这比 hack 具有更多的功能......

问题是这样的:有没有办法设置静态变量,所以这个选择可以根据给定的参数询问不同的视图?

【问题讨论】:

你为什么不想要重复的代码?那有什么问题?动态sql是另一种方法。还有为什么要在 SP 中使用视图,为什么不直接使用基础表,并且通过管理这些视图,这些视图似乎正在访问相同的表,除了过滤矿井与所有表。您可以扩展查询,然后将其放在单个语句中并进行适当的过滤。您可以发布视图定义吗? 不想重复代码的明显原因是重构和保持我们的代码库尽可能小。如果我们稍后要在此过程中更改某些内容,我们将不得不在多个地方进行,这是一件耗时且昂贵的事情。 :) 使用不同视图的原因是我们数据库中的表很大,并且有很多不需要的信息,直接访问表意味着我必须编写大量逻辑才能将这些信息输出到他正确的顺序。由于我在一家公司工作,因此无法发布视图定义。对不起:) 它可能在小型解决方案中始终直接进入表格,并将所有逻辑放在 sp 中,但这些视图用于代码中,而不仅仅是在 SP 中。在调整程序的行为时,直接使用表也是一个弱点。顾问可以改变观点并使程序以与通常不同的方式运行,这很有价值。直接对表格进行编程通常不是一个好主意,并且只在两个地方更改代码,很快就会增加几个,然后就可以了……总的来说,我完全不同意你的逻辑:) 【参考方案1】:

简单的方法:

IF @allProjects = 1
BEGIN
    SELECT TOP(@top) subtaskid,activityid FROM view_project_all v;
END
ELSE
    SELECT TOP(@top) subtaskid,activityid FROM view_project_mine v;
BEGIN
END

如果您愿意,您可以创建一个合并这些表的视图,然后针对该视图执行查询:

SELECT subtaskid, activityid, 1 as allProjects FROM view_project_all
UNION ALL
SELECT subtaskid, activityid, 0 as allProjects FROM view_project_mine

查询:

SELECT TOP(@top) subtaskid,activityid FROM view_project_mine_all_union v WHERE allProjects = @allProjects;

【讨论】:

查看编辑,使用两个视图的联合和一个鉴别器 (allProjects) 创建一个新视图。 那也行不通,这是因为两个分离视图中的值应该是分离的。如果不是,我将不需要两个视图 :) 您仍然可以创建第三个视图,但仅用于此 SP 的目的。 我不明白如何将两者分开。那么需要更多的选择,以确定联合视图的每个部分中有多少记录,以便我们只获得属于每个视图的行?并且联合是否对行进行“排序”,以便第一个视图中的行排在第一位,最后一个排在最后,或者它们是混合的? @BjørnØyvindHalvorsen。您将拥有三个视图:1.view_project_mine、2.view_project_all、3.view_project_union(包含来自 1 和 2 的记录)。 _mine 和 _all 不变。继续在别处使用它们而无需更改。 _all 就像将 1 和 2 粘在一起并添加一个字段来确定来源 ([allProjects])。您需要查询其中一个,但您只知道哪个取决于 SP 参数@allProjects。查询[allProjects] = @allProjects上的新视图和过滤器。【参考方案2】:

你可以使用 if

 if @allProjects = 1
       SELECT subtaskid,activityid FROM view_all_projects
 else
       SELECT subtaskid,activityid FROM view_project_mine

如果您的问题过于简单化,那么您可以将结果放入临时表中。

或者也许您可以优化您的项目视图,使其包含项目所有者并尝试

 SELECT subtaskid, activityId FROM view_projects
 WHERE (projectowner = USER) OR (@allprojects=1)

【讨论】:

【参考方案3】:

你可以放一个简单的 if else 循环

If @allProjects = 1
begin 
SELECT TOP(@top) subtaskid,activityid from view_project_all
end
else
begin 
SELECT TOP(@top) subtaskid,activityid from view_project_mine
end

【讨论】:

以上是关于存储过程,并从两个几乎相同的视图中选择的主要内容,如果未能解决你的问题,请参考以下文章

存储过程非常慢,与具有相同结构的快速视图相比

Linq to SQL - 视图与存储过程

SQL Server 2005 视图与物化视图与存储过程

哪个存储过程使用哪个视图?

如何使用plsql导出oracle数据建表语句,存储过程,视图.以及表中数据

在存储过程中使用表变量而不是仅从表或视图中选择?