|
| 1 | +--- |
| 2 | +title: "OQL Statements" |
| 3 | +url: /refguide/oql-statements/ |
| 4 | +beta: true |
| 5 | +weight: 210 |
| 6 | +aliases: |
| 7 | + - /refguide/oql-delete-statement/ |
| 8 | +--- |
| 9 | + |
| 10 | +{{% alert color="warning" %}} This feature is experimental. For more information, see [Release Status](/releasenotes/release-status/). {{% /alert %}} |
| 11 | + |
| 12 | +## Introduction |
| 13 | + |
| 14 | +From Mendix version 11.1, you can delete objects in bulk using OQL `DELETE` statements. From Mendix version 11.3, it is also possible to update object attributes in bulk using OQL `UPDATE` statements. |
| 15 | + |
| 16 | +OQL statements are translated to SQL statements that are sent to the database. |
| 17 | +This can be much faster than retrieving the objects in a microflow and then updating or deleting the resulting list. |
| 18 | + |
| 19 | +This feature is experimental and currently only accessible through the Java API by writing a Java action. |
| 20 | + |
| 21 | +## Java API for OQL updates |
| 22 | + |
| 23 | +OQL Statements can be executed using the `Core.createOqlStatement` Java API. For example: |
| 24 | + |
| 25 | +```java |
| 26 | +Core.createOqlStatement("DELETE FROM Module.Customer WHERE Name = 'Mary'").execute(context) |
| 27 | +``` |
| 28 | + |
| 29 | +You can pass values as parameters to the query. For example: |
| 30 | + |
| 31 | +```java |
| 32 | +Core.createOqlStatement("DELETE FROM Module.Customer WHERE Name = $nameParam") |
| 33 | + .setVariable("nameParam", customerName) |
| 34 | + .execute(context) |
| 35 | +``` |
| 36 | + |
| 37 | +The `execute()` method returns the number of objects that were affected by the statement. |
| 38 | + |
| 39 | +## `DELETE` Statement {#oql-delete} |
| 40 | + |
| 41 | +The syntax of `DELETE` statements is: |
| 42 | + |
| 43 | +```sql |
| 44 | +DELETE FROM <entity> WHERE <condition> |
| 45 | +``` |
| 46 | + |
| 47 | +`condition` can be anything that can appear in an OQL [WHERE clause](/refguide/oql-clauses/#where). |
| 48 | + |
| 49 | +### OQL `DELETE` Limitations |
| 50 | + |
| 51 | +* You cannot use OQL `DELETE` with entities that have associations with non-default delete behavior. These are associations that use either "Delete as well" or "Delete only if not associated". |
| 52 | +* You cannot use OQL DELETE to delete objects of type `System.FileDocument` or any specialization of it. |
| 53 | +* General [limitations](#oql-limitations) for OQL statements apply. |
| 54 | + |
| 55 | +## `UPDATE` Statement {#oql-update} |
| 56 | + |
| 57 | +The syntax of `UPDATE` statements is: |
| 58 | + |
| 59 | +```sql |
| 60 | +UPDATE <entity> |
| 61 | +SET { <attribute> = <expression> } [ ,...n ] |
| 62 | +WHERE <condition> |
| 63 | +``` |
| 64 | + |
| 65 | +`entity` is the entity whose objects are being updated. |
| 66 | + |
| 67 | +`attribute` is an attribute of the entity that is being updated. Multiple attributes can be updated in the same statement. |
| 68 | + |
| 69 | +`expression` is a new value of an attribute. Any [OQL expression](/refguide/oql-expressions) is allowed. The value type of the expression should match the attribute type according to [type coercion precedence](/refguide/oql-expression-syntax/#type-coercion). |
| 70 | + |
| 71 | +`condition` can be anything that can appear in an OQL [WHERE clause](/refguide/oql-clauses/#where). |
| 72 | + |
| 73 | +Example: |
| 74 | + |
| 75 | +```sql |
| 76 | +UPDATE |
| 77 | + Module.Customer |
| 78 | +SET |
| 79 | + TotalAmount = ( |
| 80 | + SELECT SUM(Amount) |
| 81 | + FROM Module.Order |
| 82 | + WHERE Module.Order_Customer/Module.Customer/ID = Module.Customer/ID |
| 83 | + ), |
| 84 | + Location = Module.Customer_Address/Module.Address/City, |
| 85 | + Name = UPPER(Name) |
| 86 | +``` |
| 87 | + |
| 88 | +### OQL `UPDATE` Limitations |
| 89 | + |
| 90 | +* At the moment, it is only possible to update attributes, not associations. |
| 91 | +* If a subquery or a long path over a many-to-one or many-to-many association is used as `expression`, it can result in multiple values. In that case, a database-level exception will occur when running the statement. |
| 92 | +* In case of inheritance, it is not possible to simultaneously update an attribute and use that attribute in an expression to update an attribute on another inheritance level. See example in the section below. |
| 93 | +* General [limitations](#oql-limitations) for OQL statements apply. |
| 94 | + |
| 95 | +#### Example of mixed attribute update |
| 96 | + |
| 97 | +To clarify the limitation on simultaneous update of different levels of inheritance, let's use the following model as an example. |
| 98 | + |
| 99 | +{{< figure src="/attachments/refguide/modeling/domain-model/oql/oql-update-mixed-attr.png" >}} |
| 100 | + |
| 101 | +The following statement will pass. It uses an attribute on one level of inheritance to update the attribute on the other level, which is allowed as long as that attribute is not being updated too. |
| 102 | + |
| 103 | +```sql |
| 104 | +UPDATE |
| 105 | + Module.SubEntity |
| 106 | +SET |
| 107 | + GeneralizationAttribute = SpecializationAttribute |
| 108 | +``` |
| 109 | + |
| 110 | +The following statement will fail. This time, the attribute that is used to update the attribute. on another inheritance level is being updated itself. |
| 111 | + |
| 112 | +```sql |
| 113 | +UPDATE |
| 114 | + Module.SubEntity |
| 115 | +SET |
| 116 | + GeneralizationAttribute = SpecializationAttribute, |
| 117 | + SpecializationAttribute = 1 |
| 118 | +``` |
| 119 | + |
| 120 | +## Joins |
| 121 | + |
| 122 | +You cannot directly join other entities in the `FROM` clause of OQL `DELETE` or in the `UPDATE` clause of OQL `UPDATE`. However, you can achieve the same result using long paths or subqueries. For example: |
| 123 | + |
| 124 | +```sql |
| 125 | +DELETE FROM Module.Order |
| 126 | +WHERE Module.Order_Customer/Module.Customer/Name = 'Mary' |
| 127 | +``` |
| 128 | + |
| 129 | +or |
| 130 | + |
| 131 | +```sql |
| 132 | +UPDATE Module.Order |
| 133 | +SET CustomerName = 'Mary' |
| 134 | +WHERE ID IN ( |
| 135 | + SELECT ID |
| 136 | + FROM Module.Order |
| 137 | + INNER JOIN Module.Customer ON Module.Customer/CustomerID = Module.Order/CustomerID |
| 138 | + WHERE Module.Customer/Name = 'Mary' ) |
| 139 | +``` |
| 140 | + |
| 141 | +## General limitations for OQL statements {#oql-limitations} |
| 142 | + |
| 143 | +* OQL statements can be used only with persistable entities. |
| 144 | +* Entity access rules are not applied to any OQL statements. |
| 145 | +* No event handlers will be executed. |
| 146 | +* Runtime and client state will not be updated with the changes. |
0 commit comments