Informix Error -384
-384 Cannot modify non simple view.
This statement attempts to modify (insert, delete, or update) rows in a view which does not have an appropriate INSTEAD OF trigger defined. Starting with version 9.40, you can define an INSTEAD OF trigger on a view. Without an INSTEAD OF trigger, this view is not modifiable because it is based on a SELECT statement that joins two or more tables or that selects calculated values or literal values. (You can DELETE from a view that selects from a single table even if some calculated values are selected.) Direct the statement against the actual table on which the view is based or define an INSTEAD OF trigger on the view to make it modifiable.
Oninit® Troubleshooting Guidance
Reasons / Common Causes
-384 fires on INSERT/UPDATE/DELETE against a view that isn't "simple" enough to be
inherently modifiable, and doesn't have an INSTEAD OF trigger to bridge the gap — a
multi-table join, or a view containing calculated/literal values, doesn't map cleanly back to a
single row in a single underlying table.
- A modification attempt against a view built on a multi-table join — there's no unambiguous single table for the server to apply the change to.
- A modification attempt against a view containing calculated or literal values in its select list — these have no underlying storage to write back to.
- No
INSTEAD OFtrigger defined on the view to explicitly handle how a modification should be translated into changes on the underlying base table(s).
Solutions / Resolution
- Direct the modification statement to the underlying base table directly, per the official guidance, instead of the view, if that's a viable option for the application.
- Define an
INSTEAD OFtrigger on the view (9.40+) to explicitly translate modifications into the appropriate changes against the underlying table(s), if modifying through the view is genuinely required.
Examples
Modifying the underlying table directly instead of the view
CREATE VIEW customer_orders AS
SELECT c.customer_id, c.name, o.order_id, o.total
FROM customers c, orders o
WHERE c.customer_id = o.customer_id;
UPDATE customer_orders SET total = 500 WHERE order_id = 1001;
-- -384: customer_orders is a multi-table join, not simply modifiable
-- Fix — update the underlying table directly:
UPDATE orders SET total = 500 WHERE order_id = 1001;
Defining an INSTEAD OF trigger to enable modification through the view
CREATE TRIGGER customer_orders_upd INSTEAD OF UPDATE ON customer_orders
REFERENCING NEW AS new OLD AS old
FOR EACH ROW (
UPDATE orders SET total = new.total WHERE order_id = old.order_id
);
Diagnostic Checks
- Check the view's defining query for a multi-table join, calculated columns, or literal values — any of these makes it "non-simple."
- Check whether an
INSTEAD OFtrigger already exists on the view for the attempted operation.
Related Errors / Related Topics
- -322 — "Cannot Alter view, Rename view or Create a trigger on a view." A related view
restriction — this error's
INSTEAD OFexception is the same one referenced there. - -365 — "Cursor must be defined on simple SELECT for FOR UPDATE." A related "must be simple" restriction, in the cursor-update context instead of the view-modification context.
Either modify the underlying base table directly, or add an INSTEAD OF trigger to the view if
modification through the view itself is genuinely required.