When you deploy a procedure, function or package that has a compilation error, the object is still created, and you can still apply grants on them. This is convenient when deploying a large number of objects, meaning you don’t have to get them all in the right order. After deploying your schema, you can just recompile the invalid objects.
Unfortunately, this doesn’t work for views. Now, normally if you create a view with compilation errors, the view will not be created at all; for a deployment script, however, you could use CREATE FORCE VIEW that means the view will be created (but marked invalid).
Let’s say you have a view that depends on a table that doesn’t exist yet – and won’t exist until much later in your deployment scripts. So you create the view with the FORCE option – success. Then, you apply the GRANTs for the view, and get this:
ORA-04063: view "x" has errors
Why? If you try to grant on a procedure, function or package that has errors, it works fine. For views, apparently, this is not allowed.
Obviously, to solve this you might do the hard work and reorder your deployment scripts so that they create every object in the perfectly correct order, avoiding compilation errors entirely. If you have a large number of objects to deploy, this might be more trouble than you want. Well, there is a workaround:
1. Create the view, minus the bit that causes a compilation error.
2. Apply the grant.
3. Recreate the view, compilation error and all. The grant will remain.
Why might this be useful? In my case, we have two databases connected by database links (on both sides); and we need to deploy a large number of objects to both instances. They are managed by different teams, so we want to be able to deploy the changes to each independently. For the most part, the objects on “our side” compile fine, except for some views that refer to objects on the other side of the database link; but they won’t exist until the other team deploys their changes. We could even have a chicken-and-egg problem, when their views refer to objects on our instance; either way, some of the objects cannot be created error-free until both deployments have been completed.
As it stands, we have two options: deploy everything as best we can, then afterwards (when both deployments have completed), recompile the invalid objects and apply the view grants. An alternative is to use this workaround.
TEST CASE #1: cannot grant on a view with errors
SQL> create or replace force view testview as select 1 as col from bla; Warning: View created with compilation errors. SQL> grant select on testview to someone; ORA-04063: view "USER.TESTVIEW" has errors SQL> select grantee, privilege from user_tab_privs where table_name = 'TESTVIEW'; no rows selected
TEST CASE #2: grant on a view with errors
SQL> create or replace view testview as select 1 as col from dual; View created. SQL> grant select on testview to someone; Grant succeeded. SQL> create or replace force view testview as select 1 as col from bla; Warning: View created with compilation errors. SQL> select grantee, privilege from user_tab_privs where table_name = 'TESTVIEW'; GRANTEE PRIVILEGE ======= ========= SOMEONE SELECT
The above has been tested on Oracle 10gR2 and 11gR2. Should this mean that Oracle should not really raise ORA-04063 in this case? I think so.