Enterprise Grafana Cloud
Last reviewed: May 22, 2026

Oracle query editor

The Oracle query editor allows you to write raw SQL queries and visualize the results in Grafana panels. You can access the query editor from a dashboard panel in edit mode or from the Explore page.

For general information on Grafana query editors, refer to Query and transform data.

Before you begin

Query editor options

The query editor provides the following options:

OptionDescription
Format asChoose Time series or Table output format.
Show HelpDisplay inline documentation with a sample query and macro reference.

Template variables are suggested automatically in the Monaco editor autocomplete when you type $ or ${.

Query as time series

When formatting data as time series, the query must include a time column containing either a SQL datetime/timestamp value or a numeric value representing Unix epoch time in seconds.

Grafana interprets date and timestamp columns without an explicit timezone as UTC.

Any column except time and metric is treated as a value column. Return a column named metric to use its value as the series name.

Example time-series query

SQL
SELECT
  $__timeGroup(time_date_time, '5m') AS time,
  MIN(value_double),
  'MIN' as metric
FROM test_data
WHERE $__timeFilter(time_date_time)
GROUP BY $__timeGroup(time_date_time, '5m')
ORDER BY time

Query as table

Set Format as to Table to return results as a table. Any SQL query is valid in table format. Use the SQL AS keyword to rename columns in the output.

SQL
SELECT hostname, cpu_usage, memory_usage
FROM system_metrics
WHERE ROWNUM <= 100

Macros

Macros simplify queries by providing dynamic elements such as time range filters. The Oracle data source expands macros into Oracle-specific SQL before executing the query.

MacroDescriptionExpands to
$__time(column)Alias the column as time.column AS time
$__timeEpoch(column)Convert a date/timestamp column to epoch milliseconds, aliased as time.(column - TO_TIMESTAMP(...)) * 24*60*60*1000 AS time
$__timeFilter(column)Filter by the dashboard time range.column BETWEEN TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS') AND TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS')
$__timeFilterTZ(column)Time range filter with timezone awareness. Functionally equivalent to $__timeFilter.column BETWEEN TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS') AND TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS')
$__timeFrom()Start of the dashboard time range.TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS')
$__timeTo()End of the dashboard time range.TO_DATE('...', 'YYYY-mm-dd HH24:MI:SS')
$__timeGroup(column, 'interval'[, fill])Group timestamps into intervals for GROUP BY clauses. Optional fill value for missing data points.TO_DATE + epoch arithmetic expression
$__timeGroupTZ(column, 'interval'[, fill])Timezone-aware time grouping that preserves timezone context using CAST and EXTRACT.TRUNC(CAST(... AS TIMESTAMP WITH TIME ZONE)) + NUMTODSINTERVAL(...)
$__unixEpochFilter(column)Filter by time range using millisecond epoch values.column >= <epoch_ms> AND column <= <epoch_ms>
$__unixEpochFrom()Start of the time range as a Unix epoch in milliseconds.<epoch_ms>
$__unixEpochTo()End of the time range as a Unix epoch in milliseconds.<epoch_ms>

Note

All time macros ($__timeFrom(), $__timeTo(), $__timeFilter()) return values in the timezone configured on the data source (default UTC), regardless of the dashboard or browser timezone setting. If your Oracle data is stored in a local timezone, use $__timeFilterTZ / $__timeGroupTZ or convert explicitly in your query.

Convert time macros to a local timezone

If you need to compare macro output against columns stored in a non-UTC timezone, use Oracle’s FROM_TZ and AT TIME ZONE to convert:

SQL
SELECT *
FROM events
WHERE event_time BETWEEN
  FROM_TZ(CAST($__timeFrom() AS TIMESTAMP), 'UTC') AT TIME ZONE 'America/New_York'
  AND
  FROM_TZ(CAST($__timeTo() AS TIMESTAMP), 'UTC') AT TIME ZONE 'America/New_York'

Alternatively, convert your stored column to UTC for comparison:

SQL
SELECT
  $__time(event_time),
  value
FROM events
WHERE FROM_TZ(CAST(event_time AS TIMESTAMP), 'America/New_York') AT TIME ZONE 'UTC'
  BETWEEN $__timeFrom() AND $__timeTo()

Fill modes

The $__timeGroup and $__timeGroupTZ macros accept an optional fill parameter to handle missing data points in time-series queries:

Fill valueBehavior
NULLFill gaps with NULL values.
previousUse the previous value in the series. If no previous value exists, NULL is used.
Numeric (for example, 0)Fill gaps with the specified number.

Example with fill:

SQL
SELECT
  $__timeGroup(created_at, '1h', 0) AS time,
  COUNT(*) as count
FROM events
WHERE $__timeFilter(created_at)
GROUP BY $__timeGroup(created_at, '1h', 0)
ORDER BY time

Brace notation

The Oracle data source supports brace notation $__macro{...} as an alternative to parentheses. Use brace notation when your macro arguments contain parentheses or complex expressions.

Note

Use one notation style per query. If any macro in the query uses braces, all macros in that query must also use braces.

Examples:

SQL
$__timeGroup{dateColumn, '5m'}
$__timeGroup{SYS_DATE_UTC(SDATE), '5m'}
$__timeGroup{FROM_TZ(CAST(SDATE as timestamp), 'UTC'), '1h'}

Timezone-aware macros

The timezone-aware macros ($__timeGroupTZ and $__timeFilterTZ) preserve timezone information in your queries. Use these macros when working with data across different time zones or when the data source timezone differs from UTC.

Example with timezone-aware macros

SQL
SELECT
  $__timeGroupTZ(timestamp_column, '5m') as time,
  metric_name as metric,
  AVG(value) as value
FROM measurements
WHERE $__timeFilterTZ(timestamp_column)
GROUP BY $__timeGroupTZ(timestamp_column, '5m'), metric_name
ORDER BY time

Complex timestamp expressions

Use brace notation for expressions that involve casting or timezone conversion:

SQL
SELECT
  $__timeGroupTZ{FROM_TZ(CAST(SDATE as timestamp), 'UTC'), '1h'} as time,
  metric_name as metric,
  value
FROM your_table
WHERE $__timeFilterTZ{FROM_TZ(CAST(SDATE as timestamp), 'UTC')}
GROUP BY $__timeGroupTZ{FROM_TZ(CAST(SDATE as timestamp), 'UTC'), '1h'}, metric_name
ORDER BY time

Note

When using timezone-aware macros, use $__timeFilterTZ in the WHERE clause to maintain timezone consistency throughout the query.

Query examples

Monitor CPU usage over time

SQL
SELECT
  $__timeGroup(sample_time, '5m') AS time,
  hostname as metric,
  AVG(cpu_percent) as value
FROM system_metrics
WHERE $__timeFilter(sample_time)
GROUP BY $__timeGroup(sample_time, '5m'), hostname
ORDER BY time

Count events per hour with gap filling

SQL
SELECT
  $__timeGroup(event_time, '1h', 0) AS time,
  event_type as metric,
  COUNT(*) as count
FROM audit_log
WHERE $__timeFilter(event_time)
GROUP BY $__timeGroup(event_time, '1h', 0), event_type
ORDER BY time

Table query with row limit

SQL
SELECT
  session_id,
  username,
  program,
  status,
  last_call_et as idle_seconds
FROM v$session
WHERE status = 'ACTIVE'
  AND ROWNUM <= 50
ORDER BY last_call_et DESC

Supported data types

The plugin supports standard Oracle data types and converts them to Grafana DataFrame types automatically.

Oracle typeGrafana typeNotes
NUMBER, INTEGER, FLOATNumericStandard numeric types.
BINARY_FLOAT (IBFloat)Float32Oracle-specific binary floating point.
BINARY_DOUBLE (IBDouble)Float64Oracle-specific binary double.
VARCHAR2, CHAR, NVARCHAR2StringStandard text types.
DATE, TIMESTAMPTimeUse as the time column in time-series queries.
TIMESTAMP WITH TIME ZONETimeTimezone information is preserved.
INTERVAL YEAR TO MONTHInt64Converted to total months.
INTERVAL DAY TO SECONDInt64Converted to total seconds.

The following types are not directly supported and require conversion in your SQL query:

Oracle typeRequired conversion
LONG / LONG RAWCAST(column AS VARCHAR2(4000))
CLOB / NCLOBDBMS_LOB.SUBSTR(column, 4000, 1)
BLOBExtract metadata: DBMS_LOB.GETLENGTH(column)
XMLTypeXMLSERIALIZE(CONTENT column AS VARCHAR2(4000))
RAWRAWTOHEX(column)

Query limits

Be aware of these limits when writing queries:

LimitDefaultConfigurable
Row limit1,000,000 rowsYes—set Row Limit in data source settings.
Response size16 MBYes—set GF_PLUGINS_ORACLE_DATASOURCE_MAX_RESPONSE_SIZE (max 512 MB).
Query timeout120 secondsYes—set Dataproxy Timeout in data source settings.

Caution

Large result sets consume significant memory on the Grafana server. Use aggregation, time filtering, and ROWNUM limits to keep queries efficient.

Use Explore for ad-hoc queries

Explore lets you run Oracle queries without creating a dashboard. This is useful for:

  • Investigating incidents: Quickly check database state, session counts, or recent errors without building a panel.
  • Developing queries: Iterate on SQL and verify output before adding it to a dashboard.
  • Comparing time ranges: Use the split view to compare metrics across two time periods side by side.

To use Explore with Oracle:

  1. Navigate to Explore in the left-side menu.
  2. Select your Oracle data source from the data source dropdown.
  3. Write your SQL query in the editor.
  4. Click Run query or press Shift+Enter.

Explore supports both Table and Time series format, which you select from the Format as dropdown. Use Table format when exploring raw data, and Time series when you want to visualize trends.

Note

Queries in Explore use the same macros, limits, and timeout settings as dashboard queries.

Common query examples

These real-world examples show typical Oracle monitoring and business metric queries. Adapt the schema and column names to match your environment.

Database performance monitoring

Active sessions over time:

SQL
SELECT
  $__timeGroup(sample_time, '1m') AS time,
  COUNT(*) AS active_sessions
FROM V$ACTIVE_SESSION_HISTORY
WHERE $__timeFilter(sample_time)
GROUP BY $__timeGroup(sample_time, '1m')
ORDER BY time

System statistics (CPU usage, I/O):

SQL
SELECT
  $__timeGroup(begin_time, '5m') AS time,
  metric_name AS metric,
  ROUND(average, 2) AS value
FROM V$SYSMETRIC_HISTORY
WHERE $__timeFilter(begin_time)
  AND metric_name IN ('CPU Usage Per Sec', 'Physical Reads Per Sec', 'Physical Writes Per Sec')
GROUP BY $__timeGroup(begin_time, '5m'), metric_name, ROUND(average, 2)
ORDER BY time

Storage monitoring

Tablespace usage:

SQL
SELECT
  tablespace_name AS metric,
  ROUND(used_percent, 2) AS "Usage %"
FROM DBA_TABLESPACE_USAGE_METRICS
ORDER BY used_percent DESC

Tablespace growth over time (requires AWR or custom logging):

SQL
SELECT
  $__timeGroup(snap_time, '1d') AS time,
  tablespace_name AS metric,
  ROUND(used_mb, 2) AS value
FROM custom_tablespace_log
WHERE $__timeFilter(snap_time)
GROUP BY $__timeGroup(snap_time, '1d'), tablespace_name, ROUND(used_mb, 2)
ORDER BY time

Session and connection monitoring

Current sessions by status:

SQL
SELECT
  status,
  COUNT(*) AS count
FROM V$SESSION
WHERE username IS NOT NULL
GROUP BY status

Wait events (top 10):

SQL
SELECT
  event AS metric,
  total_waits AS value
FROM V$SYSTEM_EVENT
WHERE wait_class != 'Idle'
ORDER BY total_waits DESC
FETCH FIRST 10 ROWS ONLY

Business metrics

Order volume over time:

SQL
SELECT
  $__timeGroup(order_date, '1h') AS time,
  COUNT(*) AS orders,
  SUM(total_amount) AS revenue
FROM orders
WHERE $__timeFilter(order_date)
GROUP BY $__timeGroup(order_date, '1h')
ORDER BY time

SLA compliance (response time percentiles):

SQL
SELECT
  $__timeGroup(request_time, '5m') AS time,
  PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY response_ms) AS p95_ms,
  PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY response_ms) AS p99_ms
FROM api_requests
WHERE $__timeFilter(request_time)
GROUP BY $__timeGroup(request_time, '5m')
ORDER BY time

Note

Queries against V$ and DBA_ views require the appropriate privileges. Refer to Create a least-privilege database user for permission setup.

Next steps