About IDO Derived Property SQL Expressions
A derived property in Mongoose is a property whose value is computed by a SQL expression at runtime, it is not stored in a database column. The SQL expression for the computation is entered on the Implementation tab of the IDO Properties form. You must check out the IDO on the IDOs form. Click the New Property button and create a Derived Property.
The IDO runtime injects the expression directly into the Select clause of the generated query from the IDO. Understanding the syntax requirements and performance implications is essential to create effective derived properties.
You can use the derived property for faster development creating inline expressions executed as sub-queries in IDO calls within Mongoose. Because it is a part of the IDO infrastructure it is more accessible for development, within the Mongoose application in the IDO. Not requiring direct access to the database behind the application allows for this development to occur in the Infor Cloud Environments where Infor maintains the database and all the security that is necessary for access.
Syntax requirements
- Must be a valid SQL expression - The expression is injected directly into the
SELECTclause of the generated query. Any SQL syntax error causes the entire IDO load to fail. Test the SQL syntax in SQL Server Management Studio before trying to use in Mongoose. - Must return a single scalar value - No multi-row results; the expression becomes one column in the
SELECT. If you see the error Sub-query returned more than one row, a derived property expression is likely returning multiple rows. UseSELECT TOP 1in sub-queries to prevent this. - Reference table columns using the table alias - The IDOs base table uses an alias, typically
t0, t1, etc. Reference columns with the alias prefix. The alias is defined on the IDO Tables form for a given table in an IDO. - Use parentheses around sub-queries - Wrap any sub-query in parentheses, for example:
(SELECT TOP1 col FROM table WHERE ...). - Must match the declared data type - If the property is declared as
INT, the expression must return an integer-compatible value. Mismatched types cause runtime conversion errors. - No trailing semicolons - Te expression is embedded in a larger query. A semicolon would terminate the query prematurely.
- No GO or batch separators - The expression is a single inline expression, not a batch script.
- If using
SELECT TOP 1in your derived property it is best practice to have anORDER BYon the query. For exampleSELECT TOP 1 FROM table view ORDER BY column1. TheORDER BYcolumn, if possible, should be an indexed column.
Formatting tips for syntax used in Derived property on the Implementation tab of an IDO Derived Property
Simple column calculation
The implementation syntax below could be used for a DerExtCost derived property. The table alias t0 is specified on the IDO Tables form:
t0.Qty * t0.UnitCost
CASE expression
CASE WHEN t0.Status = 'A' THEN 1 ELSE 0 END
Correlated sub-query
Always use TOP 1 to guarantee a single value is returned:
(SELECT TOP 1 Name FROM custaddr WHERE cust_num = t0.cust_num AND cust_seq = 0)
SQL function call
ISNULL(t0.Description, N'')
Concatenation
Combine multiple columns into a single string value:
t0.FirstName + N' ' + t0.LastName
CAST to a different format
CAST(t0.Amount AS DECIMAL(18,2))
Common pitfalls
| Pitfall | Explanation |
|---|---|
| Using column aliases in the expression | The alias is applied by the IDO automatically using the property name. Do not add your own. |
| Referencing other derived properties | Reference only base table columns, not other derived properties. |
Using SELECT * |
Only scalar expressions are allowed. Do not use SELECT *. |
| Missing Unicode prefix on string literals | Use N'...' for string literals to ensure nvarchar compatibility. |
| Not handling NULL values | Use ISNULL() or COALESCE() if NULL values could cause issues downstream. |
Table alias reference
The base table of the IDO typically gets the alias t0. Joined tables get t1, t2, etc. Check the IDO's table or view definition on the IDO Tables form to confirm which alias corresponds to which table.
Performance considerations
Aggregate expressions in sub-queries
Using aggregate functions (COUNT, SUM, MIN, MAX, etc.) in sub-queries within a derived property expressions can be expensive. The derived expression executes for every row returned by the IDO's base query.
- How many records are in the table being aggregate? - Summing a handful of records per row is acceptable. Aggregating across tens of thousands or hundreds of thousands of records per row is not recommended.
- How many records are in the IDO's base table? - The aggregate expression runs once for each row in the base result set. If the base table returns 1000 rows and each row's sub-query aggregates 10,000 records, which is a 10 million row evaluations.
Aggregate expressions are appropriate when the sub-query processes some records, for example, order lines for a single record. Then should be avoided when aggregated table contains tens of thousands of records or more per evaluation
Avoid COALESCE in WHERE clauses
Use COALESCE in the SELECT portion of a derived expression is acceptable.
(SELECT COALESCE(description, 'no description') FROM dbo.sometable WHERE id =t0.id)
However, using COALESCE in a WHERE clause prevents index usage and causes full table scans.
This is a sample of a problem that causes poor performance:
(SELECT column1 FROM dbo.sometable WHERE COALESCE(xyz, 'x') = t0.somecolumn)
WHERE clause to avoid wrapping the column. This is a better alternative:
(SELECT column1 FROM dbo.sometable WHERE (xyz = t0.somecolumn OR (xyz IS NULL AND 'x' = t0.somecolumn)))
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
| "Sub-query returned more than one row" | Sub-query returns multiple rows | Add TOP 1 to the sub-query or add a more specific WHERE clause |
| Data type conversion error | Expression returns a type that does not match the property's declared type. | Add CAST() or CONVERT() to match the declared type. |
| Invalid column name | Table alias is incorrect or column does not exist | Verify the alias on the IDO Tables form and the column name in the view or table. |
| Query time-out | Expensive aggregate or poorly filtered sub-query | Reduce the data set, add a better filtering, or avoid aggregates on large tables. |