Querying

Execute SQL queries against databases using queryExecute() or bx:query component

BoxLang provides powerful and flexible ways to execute SQL queries against your databases. You can use either the queryExecute() Built-In Function (BIF) or the bx:query component, both offering the same capabilities with different syntax styles.

📋 Overview

Database querying in BoxLang supports:

  • Parameterized Queries - Prevent SQL injection with bound parameters

  • Multiple Return Types - Get results as query objects, arrays, or structs

  • Query Caching - Cache frequently-used queries for performance

  • Query of Queries (QoQ) - Execute SQL against in-memory result sets

  • Flexible Syntax - Choose between BIF and component styles

  • Connection Pooling - Automatic connection management via HikariCP

🔧 Query Execution Methods

Using queryExecute() BIF

The queryExecute() function is the preferred method for script-based code:

// Basic query
employees = queryExecute( "SELECT * FROM employees" );

// With positional parameters
employee = queryExecute(
    "SELECT * FROM employees WHERE id = ?",
    [ 42 ]
);

// With named parameters
salesTeam = queryExecute(
    "SELECT * FROM employees WHERE department = :dept AND salary > :minSalary",
    {
        dept: "Sales",
        minSalary: 50000
    }
);

// With options
result = queryExecute(
    "SELECT * FROM products WHERE category = ?",
    [ "Electronics" ],
    {
        datasource: "myDB",
        returntype: "array",
        maxrows: 100
    }
);

Using bx:query Component

The bx:query component is ideal for template-based code islands, or when you prefer XML-style syntax. Please also note that you can also use the bx:query component inside script code as well.

🛡️ Parameterized Queries

Always use query parameters for user input to prevent SQL injection attacks.

Positional Parameters

Use ? placeholders and provide values in an array:

Named Parameters

Use :paramName placeholders and provide values in a struct:

bx:queryParam Component

For template syntax, use bx:queryParam for type-safe parameter binding:

Advanced Parameter Options

Parameters can include additional options for fine-grained control:

Parameter Options:

  • value - The parameter value

  • type - SQL type (varchar, integer, decimal, date, timestamp, bit, etc.)

  • null - Set to true for NULL values

  • list - Set to true for IN clause lists

  • separator - List separator (default: ",")

  • maxLength - Maximum length for string types

  • scale - Decimal scale for numeric types

📊 Return Types

Control how query results are returned using the returntype option.

Query Object (Default)

Returns a BoxLang Query object with rows accessible via array notation:

Array of Structs

Returns an array where each element is a struct representing a row:

Struct (Keyed by Column)

Returns a struct keyed by a specific column, with each value being a struct of the row data:

⚡ Query Caching

Cache frequently-executed queries to improve performance:

Cache Options:

  • cache - Enable caching (boolean)

  • cacheKey - Custom cache key (defaults to SQL hash)

  • cacheTimeout - Time-to-live duration

  • cacheLastAccessTimeout - Idle timeout

  • cacheProvider - Named cache provider to use

🔄 Query of Queries (QoQ)

Execute SQL queries against in-memory query objects without hitting the database:

QoQ Features:

  • Standard SQL syntax (SELECT, WHERE, ORDER BY, GROUP BY, JOIN)

  • Aggregation functions (COUNT, SUM, AVG, MIN, MAX)

  • No database round-trips

  • Ideal for filtering, sorting, and transforming result sets

QoQ Limitations:

  • Limited SQL function support compared to full databases

  • No transaction support

  • Performance depends on result set size

📈 Query Result Information

Capture metadata about query execution using the result option:

Result Struct Properties:

  • recordCount - Number of rows returned

  • columnList - Comma-delimited list of columns

  • executionTime - Query execution time in milliseconds

  • cached - Boolean indicating if result was cached

  • sql - The SQL statement executed

  • sqlParameters - Array of bound parameter values

🎛️ Query Options

Complete list of options available for queryExecute() and bx:query:

Option
Type
Description

datasource

string

Datasource name or inline struct

dbtype

string

"query" for QoQ, "hql" for Hibernate

returntype

string

"query", "array", or "struct"

columnKey

string

Column to use as struct key (when returntype="struct")

maxrows

integer

Maximum rows to return

timeout

integer

Query timeout in seconds

cache

boolean

Enable query caching

cacheKey

string

Custom cache key

cacheTimeout

duration

Cache time-to-live

cacheLastAccessTimeout

duration

Cache idle timeout

cacheProvider

string

Named cache provider

result

string

Variable name to store execution metadata

username

string

Override datasource username

password

string

Override datasource password

fetchsize

integer

Number of rows to fetch at once

📊 Query Metadata

Every query result has metadata that provides information about the query execution, columns, and result set. You can access this metadata using the getMetadata() function or the query's $bx.meta property.

Accessing Query Metadata

Metadata Structure

Query metadata includes the following keys:

Key
Type
Description

type

string

Always "Query"

recordCount

integer

Number of rows in the result set

columnList

string

Comma-delimited list of column names

columnMetadata

struct

Detailed information about each column

executionTime

integer

Query execution time in milliseconds

cached

boolean

Whether the result was retrieved from cache

cacheKey

string

Cache key if query was cached

cacheProvider

string

Cache provider name if cached

cacheTimeout

duration

Cache time-to-live duration

cacheLastAccessTimeout

duration

Cache idle timeout duration

sql

string

The executed SQL statement (when available)

sqlParameters

array

Bound parameter values (when available)

_HASHCODE

integer

Java hashcode of the query object

Column Metadata

The columnMetadata key contains detailed information about each column:

Each column has the following properties:

Property
Type
Description

name

string

Column name

type

string

BoxLang type (String, Integer, Double, DateTime, etc.)

sqltype

string

JDBC SQL type (VARCHAR, INTEGER, DECIMAL, TIMESTAMP, etc.)

index

integer

Zero-based column index in the result set

Practical Examples

Display Query Information

Debug Query Columns

Cache Performance Monitoring

Dynamic Column Mapping

Query Comparison Tool

Metadata in Result Variable

When using the result parameter, execution metadata is automatically captured:

Best Practices for Metadata

  • Use metadata for debugging - Check execution times and column information during development

  • Monitor cache performance - Log cache hits/misses in production

  • Validate data structures - Compare expected vs actual column types

  • Dynamic data handling - Use column metadata for generic data processors

  • Don't access metadata unnecessarily - Small performance cost for metadata generation

  • Don't store metadata long-term - Query structure may change over time

💡 Best Practices

Security

  • Always use query parameters for user input

  • Never concatenate user input into SQL strings

  • Validate input before querying

  • Use environment variables for credentials

Performance

  • Use connection pooling (automatic with datasources)

  • Cache static queries (categories, lookups, etc.)

  • Limit result sets with maxrows when appropriate

  • Use QoQ for in-memory filtering instead of multiple DB queries

  • Index database columns used in WHERE clauses

Code Quality

  • Use consistent syntax (BIF or component, not mixed)

  • Name result variables descriptively

  • Capture execution metadata for debugging

  • Handle empty result sets gracefully

Anti-Patterns

  • Don't use string concatenation for SQL building

  • Don't cache user-specific data without proper keying

  • Don't fetch all rows when you only need a few

  • Don't ignore errors - wrap in try/catch for critical operations

📚 Examples

Pagination

Dynamic WHERE Clauses

Batch Processing

Last updated

Was this helpful?