OraQA

Oracle Question and Answer

  • Do you have a solution to a problem? Do you have an unanswered question? Login and share it with the Oracle community. More...

Oracle News


Entries RSS feed

Comments RSS feed

How to set a table in read-only mode ?

January 9th, 2006 By Francois Degrelle

ALTER TABLE emp 
ADD CONSTRAINT read_only CHECK (1=1) DISABLE VALIDATE;

It is now, impossible to insert, update or delete anything with this table.

13 Responses to “How to set a table in read-only mode ?”

  1. laurentschneider Says:

    should not it be check 1=0?

  2. Francois Degrelle Says:

    Laurent,
    The content of the constraint has no importance. The trick is just behind the 2 words : DISABLE VALIDATE

  3. kirtandesai Says:

    Learned something new today!!!

  4. tkyte Says:

    Someone pointed out on my blog that a direct path load will bypass this, the table isn’t read only for sqlldr direct=y. Additionally, the direct=y will cause the constraint to not be effective after the direct path load.

    Neat idea though…

  5. dizwell Says:

    The only correct answer to the question as written is “You can’t”.

    If you want to know why that is the answer, then you can read http://dizwell.com/main/content/view/62/84/

  6. Laurent Schneider Says:

    good article horward. note that moving the table to a readonly tablespace, revoking every rights from everybody does not prevent the owner from dropping his own table ;-)

    The disable validate method does the trick in most case and is very handy.

    SQL> 
    SQL> create user u identified by u;
    
    User created.
    
    SQL> create tablespace tsro;
    
    Tablespace created.
    
    SQL> grant create session, create table to u;  
    
    Grant succeeded.
    
    SQL> alter user u quota 1M on tsro;
    
    User altered.
    
    SQL> create table u.t(n number) tablespace tsro;
    
    Table created.
    
    SQL> revoke create table from u;
    
    Revoke succeeded.
    
    SQL> alter user u quota 0 on tsro;
    
    User altered.
    
    SQL> alter tablespace tsro read only;
    
    Tablespace altered.
    
    SQL> connect u/u
    Connected.
    
    SQL> drop table t;
    
    Table dropped.
    
    
  7. Laurent Schneider Says:

    sorry for misspelling your name Howard, but sadly I cannot edit my comment :-(

  8. tkyte Says:

    Connor pointed out here that if you add:

    SQL> alter table T add constraint CK1 check ( 1=1) disable validate;
    SQL> alter table T disable table lock;

    the disable table lock will prevent the direct path load and the check will make the table effectively read only.

  9. dizwell Says:

    Laurent: dropping a table does not modify that table’s rows. Therefore, the table is still read-only, which I think you’ll find is the question that was asked.

    However, the question did NOT ask “how do I make a table look sort-of read only good enough for most of the time in quite a handy fashion”. So the line about doing the trick “IN MOST CASES” is a rather important qualifier that means ‘disable novalidate’ does not answer the question.

    Neither does the question read, “I want to add some spurious constraints to a table that might or might not affect execution plans, so please tell me how to go about doing this”.

    And neither did the question ask, “How do I go about preventing users from dropping indexes, rebuilding indexes online, moving a table, enabling row movement, or shrinking and compacting a table”… all of which are unmentioned consequences of disabling the table lock in Connor’s fashion, and none of which he or Tom saw fit to mention as consequences.

    So if the question was “How do I make something look read-only, without actually making it read-only, and also at the same time wreak havoc with my execution plans and my normal DBA functions”, then yeah… I guess the answers we have here will more or less suffice. But as to the question as actually posed, these are not technically correct answers, and lead to bad practice and poor outcomes.

    We should also beware weasel words like “effectively”. Making something “effectively” read only is not the same as making something “actually” read only, and it is disingenuous to suggest they pretty much are. Next, we’ll have people saying, “I recovered my database”, when what they mean is “Actually, I lost half an hour’s worth of data botching a recovery”, and we’ll be expected to say, “Yeah, but it’s effectively been recovered”!

    The question as written has one simple answer: “You can’t”. The business problem giving rise to the question has, however, many possible solutions, of which the enable validated constraint (and it doesn’t need to be a new one created for the occasion) is just one possible. Without qualifying the precise nature of that business problem, however, then simplistic answers are no answers at all.

  10. Laurent Schneider Says:

    I guess the proper way to prevent an user from inserting/deleting/updating a table is granting only select on that table to the user

  11. vikasa Says:

    For the rest of us, here is why DISABLE VALIDATE makes the table immune to DML. Quoting Howard J. Rogers,

    “Because if a constraint is disabled, it is not enforced… yet you want to “validate” it -in other words, you want to ensure that data conforms to the constraint’s requirements.

    So if you want to make sure the data conforms to the constraint’s requirements, but you won’t let me check each data change as it is made to see that it conforms… I have only one choice, which is to lock the table out from all DML attempts.

    It was invented in 8i to allow people to drop indexes in order to re-create them. Dropping an index that is associated with a constraint implies disabling the constraint… but that would then leave the table open to “bad” DML. The new constraint state was invented to allow you to disable the constraint enough to let you drop the index associated with it, but not permit dodgy DML to take place”

  12. Robertc Says:


    dizwell Says:
    If you want to know why that is the answer, then you can read http://dizwell.com/main/content/view/62/84/

    Howard you sure the link is right ???
    (got the “Welcome to Dizwell!” page)

  13. Francois Degrelle Says:

    Robert, here is a correct link:
    http://dizwell.com/main/content/view/62/84/index.php?option=com_content&task=view&id=62&Itemid=84

Leave a Reply

You must be logged in to post a comment.

RSS feed for comments on this question