Error
Error Code:
1395
MariaDB Error 1395: Deleting from Join View Restricted
Description
This error occurs when you attempt to execute a DELETE statement directly on a MariaDB view that is defined using a JOIN operation involving two or more tables. MariaDB's SQL engine cannot unambiguously determine which rows from the underlying base tables should be removed when a delete is performed on such a complex view, making it non-updatable for DELETE operations.
Error Message
Can not delete from join view '%s.%s'
Known Causes
3 known causesView Defined with JOIN
The target view in your DELETE statement is constructed using a JOIN clause, which inherently makes it a non-updatable view for direct DELETE operations.
Ambiguous Deletion Target
MariaDB cannot unambiguously identify and delete specific rows from the underlying base tables when a DELETE is issued against a view formed by joining multiple tables.
Direct DML on Complex Views
MariaDB restricts direct Data Manipulation Language (DML) operations like DELETE on views that are complex, such as those involving JOINs, aggregations, or subqueries.
Solutions
3 solutions available1. Simplify the View for Deletion medium
Rewrite the view to include only one table and a primary key for direct deletion.
1
Identify the base table in your join view that contains the primary key of the records you intend to delete. This is often the 'first' table in your `FROM` clause or the one that is not a foreign key referencing another table in the view.
2
Create a new view that selects only the primary key and any other necessary columns from that single base table. This simplified view will be updatable.
CREATE VIEW deletable_view AS SELECT t1.id, t1.column1, t1.column2 FROM table1 t1;
3
Delete records from this new, simplified view.
DELETE FROM deletable_view WHERE id = 123;
4
If you need to delete based on criteria involving joined tables, you'll need to join the simplified view back to the other tables in your `DELETE` statement. However, this can become complex and may still be restricted. It's generally more reliable to delete from the simplified view.
2. Delete Directly from the Base Table easy
Perform the deletion directly on the underlying table that holds the records you want to remove.
1
Examine the definition of your join view to determine which underlying table contains the rows you wish to delete. For example, if your view joins `orders` and `customers`, and you want to delete an order, you'll target the `orders` table.
2
Construct a `DELETE` statement targeting the identified base table. Use a `WHERE` clause that references columns from the base table or columns that can be used to uniquely identify the rows to be deleted (potentially by joining to other tables within the `DELETE` statement if necessary, but be cautious).
DELETE FROM orders WHERE order_id = 456;
3
Alternatively, if you need to delete based on criteria from a joined table, you can use a subquery or a join within your DELETE statement. Ensure the subquery or join accurately identifies the rows in the target table for deletion.
DELETE FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE country = 'USA');
3. Use an `INSTEAD OF` Trigger for Complex Deletions advanced
Implement an `INSTEAD OF` trigger to define custom logic for deleting from the join view.
1
Understand that `INSTEAD OF` triggers are not directly supported by MariaDB for `DELETE` operations on views in the same way they might be in other RDBMS. MariaDB's approach to updatable join views is more restrictive. This solution is more theoretical for MariaDB and may require workarounds or a different RDBMS for true 'INSTEAD OF' deletion behavior.
2
If your MariaDB version and specific view structure *were* to support complex updatability (which is rare for DELETE on join views), you would create a trigger that intercepts the DELETE operation on the view. This trigger would then contain `DELETE` statements targeting the appropriate base tables.
DELIMITER //
CREATE TRIGGER delete_from_my_join_view INSTEAD OF DELETE ON my_join_view
FOR EACH ROW BEGIN
-- Example: Delete from table1 based on row identifier from the view
DELETE FROM table1 WHERE table1.id = OLD.id;
-- Add DELETE statements for other tables if necessary, ensuring uniqueness
END; //
DELIMITER ;
-- Then attempt to delete from the view:
-- DELETE FROM my_join_view WHERE view_id = 789;
3
Note: The ability to create `INSTEAD OF DELETE` triggers on join views is highly dependent on the view's complexity and MariaDB's specific implementation. Many join views will not be considered updatable at all, rendering this approach unusable. The primary restriction is often that the view must reference at least one table that has a primary key and is not involved in a join where the join condition is not equality or involves a subquery.