1

文档说通过视图引用每个表,以便修改或删除视图未引用的列而不会使相关对象无效。我没有找到一个真正有意义的案例。

如果依赖对象引用表中的特定列,则修改或删除其他列实际上不会通过 a 间接view或直接改变依赖对象的状态。

4

2 回答 2

1

通过视图做所有事情的文档指南是荒谬的,应该被忽略。

我从未见过有人遵循这些准则。甚至没有甲骨文。Oracle 文档通常很棒,但每本手册都包含一些错误和奇怪的意见。

一个好的程序可以最小化间接级别和对象数量。一切之上的额外层需要一个很好的理由。避免一些奇怪的情况,无论如何都是由糟糕的编程实践引起的,不足以证明视图的额外复杂性是合理的。

于 2017-12-30T05:06:05.770 回答
1

如果依赖对象引用表中的特定列,修改或删除其他列确实不会改变依赖对象的状态......

是的,但是如果您没有明确引用列怎么办?

使用上一个问题中的设置,这是一个有意义的示例:

create table test (num1 number, num2 number);

create or replace procedure refvirew_intab is
begin
  for r in (select * from test) loop
    dbms_output.put_line(r.num1);
  end loop;
end;
/

此时所有三个对象都有效。如果我删除未使用的num2列:

alter table test drop column num2;

然后程序无效:

OBJECT_NAME          OBJECT_TYPE         STATUS 
-------------------- ------------------- -------
REFVIREW_INTAB       PROCEDURE           INVALID
TEST                 TABLE               VALID  
VEXTEST              VIEW                VALID  

如果重新添加了该列并且针对视图创建了该过程:

create or replace view vextest as (select num1 from test);

create or replace procedure refvirew_intab is
begin
  for r in (select * from vextest) loop
    dbms_output.put_line(r.num1);
  end loop;
end;
/

然后修改表现在没有效果:

alter table test drop column num2;

Table TEST altered.

select object_name, object_type, status
from user_objects
where object_name in ('TEST' ,'VEXTEST', 'REFVIREW_INTAB')
order by object_name;

OBJECT_NAME          OBJECT_TYPE         STATUS 
-------------------- ------------------- -------
REFVIREW_INTAB       PROCEDURE           VALID  
TEST                 TABLE               VALID  
VEXTEST              VIEW                VALID  

现在,您似乎已经知道,这仅适用于select *. 如您在问题中所建议的,如果表版本已select num1删除第二列,则对过程没有影响。并且select *不赞成使用。在这种情况下,只要确实没有对删除的列的引用,该过程就会自动重新编译并成功。

另一种情况是,如在前面的示例中一样,如果您在未指定列名的情况下插入表(同样不赞成)。在这种情况下,更改表定义将使该过程无效,这可能更具灾难性,因为如果您最终得到不同数量/顺序/类型的列,它将无法成功重新编译。如果您通过触发器插入视图,instead of那么该过程将不在乎。(触发器会,然后可能不会重新编译,这取决于它在做什么)。不过,这与文档中的第一个项目符号更相关,而不是您要问的第二个项目符号;但也适用于删除列。

因此,这是否真的有用的建议值得商榷。我确信有些人在select *不指定列名的情况下使用或插入,有些人使用视图来避免那些偶尔出现的副作用。我不确定我是否能看到这样一种场景,即为了避免依赖对象失效的可能性而使用一层视图是否值得额外管理,但有些人可能会这样做。

如果您看到对象无效,即使是暂时无效,您可能做错了什么 - 架构更改通常应该以计划和受控的方式完成,以便正确处理副作用,包括对依赖对象的协调更新。但同样,其他人会有不同的意见和优先事项。

于 2017-12-29T19:09:34.100 回答