12. SQL — Manual Execution
Use with caution
Only use these functions when the CRUD functions cannot express your query. Always sanitize inputs to prevent SQL injection.
manuallyExecuteReadSql(sqlCommand)
async· returnsExpandoObject[]
Executes a raw SQL SELECT query and returns result rows as an array of plain JS objects. Returns [] if no rows match.
Prop
Type
const rows = await context.functions.manuallyExecuteReadSql(
"SELECT ID, Name, Email, CreateDate FROM Users WHERE SystemStatusID = 1"
);
rows.forEach(row => log(row.Name + " — " + row.Email));
Returned value — an array of plain objects, one per row, keyed by the column names in your SELECT. Returns [] if no rows match:
[
{ "ID": "1", "Name": "Alice Johnson", "Email": "alice@example.com", "CreateDate": "2025-04-01T08:00:00Z" },
{ "ID": "2", "Name": "Bob Smith", "Email": "bob@example.com", "CreateDate": "2025-05-10T09:30:00Z" },
{ "ID": "3", "Name": "Carol White", "Email": "carol@example.com", "CreateDate": "2025-06-22T11:15:00Z" }
]
Raw SQL results return exactly the columns you select. System fields like CreateUser and ModifyUser are stored as foreign key IDs and come back as plain values unless you join them explicitly.
manuallyExecuteNonReadSql(sqlCommand)
async· returnsvoid
Executes a raw SQL INSERT / UPDATE / DELETE statement. Does not return rows.
Prop
Type
await context.functions.manuallyExecuteNonReadSql(
"UPDATE Orders SET Status = 'archived' WHERE CreateDate < '2024-01-01'"
);