Skip to Main Content
  • Questions
  • Invalid view when uderlying table changes - shoudl recompile fix it

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Jay.

Asked: February 02, 2009 - 10:12 am UTC

Last updated: February 03, 2009 - 5:18 pm UTC

Version: 10.1.2

Viewed 10K+ times! This question is

You Asked

We (all of the developers here) were under the impression that if we created a view with the "select * from tablea" syntax that a recompile would fix the view even if new columns were added or column names were changed in thh underlying table. Take this example:

1)
create table jay_test_views
as
select 'xxx' as col1, 'yyy' as col2 from dual; (good return code)

2)
create view jay_test_views_v
as
select * from jay_test_views; (good return code)

3)
select * from jay_test_views_v

col1 col2
xxx yyy

4)
alter table jay_test_views rename column col2 to col3 (good return code)

5)
select * from jay_test_views_v
ora-04063 view cmic.jay_test_view_v has errors (this is expected)

6)
alter view jay_test_views_v compile (good return code)

7)
select * from jay_test_views_v
ora-04063 view cmic.jay_test_view_v has errors (still did not work after recompile)

8)
create or replace view jay_test_views_v
as
select * from jay_test_views (good return code)

9)
select * from jay_test_views_v
col1 col3
xxx yyy (good return code with correct column names)

It is our understanding that since the view was created as a "select *" that the recompile would fix the invalid view, but it doesn't.

Also, the view is stored in the data dictionary as
"select col1, col2 from jay_test_views". Why would it not be stored as "select * from jay_test_views" ?

Thanks

and Tom said...

The "*" has always been evaluated at compile time - expanded into a list of available columns AS OF that point in time - and stored with explicit column names. This goes back many many many releases.

(note: there was a bug a long time ago - version 8.1.5 timeframe - whereby "select t.* from t" would accidentally NOT get expanded due to the correlation name - that was fixed, I know that bug - I filed it in 1999 myself :) )

It is not stored as select * from table because - that would be wrong. A view is defined when you put it into the database, a view is used to achieve logical independence from the table (eg: a change to the table SPECIFICALLY should not impact applications that use the view)

Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks

Jay Fowler, February 02, 2009 - 5:16 pm UTC

Just to be clear, any time the DDL of a table changes (specifically the column name changes) all views that are dependant on that table will have to be re-created with the "create or replace" syntax rather than just recompiling. True?

Thanks again.
Tom Kyte
February 03, 2009 - 9:17 am UTC

Just to be clear:

NO


In general the answer is absolutely *NOT*. Add a column to a table - does a view that was created in support of an application interface to the database need to change? Probably not - not unless the application code is going to change too - which means you are recreating the entire stack. But in general *NO*, you would not.

Rename a column? If your view accesses the column by the old name, it will obviously have to be refactored, rewritten, you are making a change to something that depends on it - just like your code that uses the view will have to be modified.

q: What are views used for?
a: they are typically used to hide from the application changes that take place to the underlying physical structures.


If you change a name of a column and the view BY YOUR REQUIREMENT needs to be modified - then so be it (just like any application that queries the view must now be modified and so on and so on)


Think of views like code (plsq - do - really - they are). A SQL Query is a subroutine, a method. If you have requirements that change (underlying physical schema is modified in a way that dramatically affects your code) your code, then change the code.

A view is SQL, SQL is code, code is code.

Michael Virnstein, February 03, 2009 - 2:40 am UTC

Just to be clear, any time the DDL of a table changes (specifically the column name changes) all
views that are dependant on that table will have to be re-created with the "create or replace"
syntax rather than just recompiling. True?

No, only the views that reference one of the changed columns:
SQL> create table t_viewtest (x number, y number);
 
Table created
 
SQL> create or replace view v_viewtest_x as select x from t_viewtest;
 
View created

SQL> create or replace view v_viewtest_y as select y from t_viewtest;
 
View created
 
SQL> alter table t_viewtest rename column y to z;
 
Table altered
 
SQL> select * from v_viewtest_x;
 
         X
----------
 
SQL> select * from v_viewtest_y;
 
select * from v_viewtest_y
 
ORA-04063: view "TBO.V_VIEWTEST_Y" has errors

"The "*" has always been evaluated at compile time ... "

Sokrates, February 03, 2009 - 1:13 pm UTC

there's still an issue with it in 10.2, where your statement is not totally true:


sokrates@10.2 > create table jay_test_views 
  2  as
  3  select 'xxxxxxxx' as col1, 'yyyyyyyyyy' as col2 from dual; 

Table created.

sokrates@10.2 > create view expanded as
  2  select * from jay_test_views; 

View created.

sokrates@10.2 > 
sokrates@10.2 > alter table jay_test_views add  constraint i_assume_this_is_the_pk primary key ( col1 );

Table altered.

sokrates@10.2 > 
sokrates@10.2 > create view not_expanded as
  2  select * from jay_test_views natural join (select col1 from jay_test_views);

View created.
sokrates@10.2 > select view_name, text from user_views where view_name in ('EXPANDED', 'NOT_EXPANDED');

VIEW_NAME
------------------------------
TEXT
--------------------------------------------------------------------------------
EXPANDED
select "COL1","COL2" from jay_test_views

NOT_EXPANDED
select * from jay_test_views natural join (select col1 from jay_test_views)


sokrates@10.2 > alter table jay_test_views rename column col2 to col3 ;

Table altered.

sokrates@10.2 > select * from expanded;
select * from expanded
              *
ERROR at line 1:
ORA-04063: view "DP.EXPANDED" has errors


sokrates@10.2 > select * from not_expanded;

COL1     COL2
-------- ----------
xxxxxxxx yyyyyyyyyy

sokrates@10.2 > desc not_expanded
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                                      NOT NULL CHAR(8)
 COL2                                               CHAR(10)


sokrates@10.2 > REM now it is getting really funny ...
sokrates@10.2 > select col2 from not_expanded;

COL2
--------
xxxxxxxx

sokrates@10.2 > select col2, col3 from not_expanded;

COL2     COL3
-------- ----------
xxxxxxxx yyyyyyyyyy

sokrates@10.2 > select col2, col3, col1 from not_expanded;
select col2, col3, col1 from not_expanded
             *
ERROR at line 1:
ORA-00904: "COL3": invalid identifier

Tom Kyte
February 03, 2009 - 2:00 pm UTC

9.2.0.8 - reproduced
10.2.0.4 - reproduced
11.1.0.7 - not reproduced

now, to see if there was a bug filed...

bug filed

Sokrates, February 03, 2009 - 4:13 pm UTC

I didn't file one because
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:6585774577187#1044434100346396541
seemed to show me it was already fixed in 11.1.0.6
Tom Kyte
February 03, 2009 - 5:18 pm UTC

see, I've got so many bits of trivia stuck in my head, I often forget what I've already seen

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library