Raw SuiteQL
Execute raw SuiteQL queries when you need full control.
The query builder covers common use cases, but sometimes you need the full power of SuiteQL. The $queryRaw method is your escape hatch.
$queryRaw
const results = await ns.$queryRaw<{ id: string; companyname: string }>(
"SELECT id, companyname FROM customer WHERE isinactive = 'F' ORDER BY companyname ASC"
);The type parameter <T> controls the return type — use it to get typed results from your raw queries.
Use Cases
JOINs
SuiteQL supports joins across record types:
const data = await ns.$queryRaw<{
tranid: string;
companyname: string;
total: string;
}>(
`SELECT t.tranid, c.companyname, t.foreigntotal
FROM transaction t
INNER JOIN customer c ON t.entity = c.id
WHERE t.type = 'CustInvc'
ORDER BY t.id DESC`
);Aggregations
const summary = await ns.$queryRaw<{
entity: string;
total_invoices: string;
total_amount: string;
}>(
`SELECT entity, COUNT(*) AS total_invoices, SUM(foreigntotal) AS total_amount
FROM transaction
WHERE type = 'CustInvc'
GROUP BY entity
ORDER BY total_amount DESC`
);Subqueries
const results = await ns.$queryRaw<{ id: string; companyname: string }>(
`SELECT id, companyname FROM customer
WHERE id IN (
SELECT entity FROM transaction WHERE type = 'SalesOrd'
)`
);Using the Connector Directly
For advanced use cases (pagination, retry control), you can use the connector directly:
import { NetSuiteClient, executeSuiteQL, executeSuiteQLPaginated } from 'suiteportal';
const client = new NetSuiteClient(config);
// Single page
const result = await executeSuiteQL(client, 'SELECT id FROM customer', {
limit: 100,
offset: 0,
});
// Auto-paginate through all results
const allRows = await executeSuiteQLPaginated(client, 'SELECT id FROM customer', {
pageSize: 1000,
maxRows: 10000,
});