Tuesday, January 16, 2024

ORA-14148: DML and DDL operations are not directly allowed on the guard-column.

Say you had a table in you production environment and you had to add a nullable column with a default value.
In your test environment however, for some reason, instead of adding the column, you recreated the table, therefore the new column is present since the beginning (in my case this happened because we are in the middle of a migration to a new version of Oracle).
Suppose then that you have a procedure duplicating some data in this table and you do this with dynamic SQL, collecting the column names from a view like ALL_TAB_COLS or DBA_TAB_COLS, because you want to be sure to skip virtual columns which cannot be inserted exactly because they are virtual.
Unlike ALL_TAB_COLUMNS or DBA_TAB_COLUMNS, ALL_TAB_COLS can return column names belonging to hidden columns or system generated columns and for this reason ALL_TAB_COLS contains additional column flags telling if a column is visible, if it is user generated, if it is an identity column and so on. 

This behavior may introduce some unexpected consequences when you run the "copy data" procedure in production:

ORA-14148: DML and DDL operations are not directly allowed on the guard-column.

This error might be raised when you try to insert a value for a column that you don't even know it existed because it was automatically added by Oracle when you added the column to the table

The nice collateral effect is that you may actually see the same procedure to succeed on the instance where the table contains the column since its creation, while it fails on the instance where the column was added at a later time, something that might drive you crazy, at least for a while.

The detailed explanation of this behavior by design is left to this thread in the Oracle forums.

So, if you are using ALL_TAB_COLS or DBA_TAB_COLS to gather column names to be used in dynamic SQL, make sure to take rows where:

... USER_GENERATED = 'YES' AND VIRTUAL_COLUMN = 'NO'.

Of course this is not the only situation where Oracle needs to use hidden columns, but so far it has been the most puzzling to be sorted out.


No comments:

yes you can!

Two great ways to help us out with a minimal effort. Click on the Google Plus +1 button above or...
We appreciate your support!

latest articles