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
- Configure the Oracle data source.
- Verify your Oracle user has
SELECTpermissions on the tables you want to query.
Query editor options
The query editor provides the following options:
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
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 timeQuery 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.
SELECT hostname, cpu_usage, memory_usage
FROM system_metrics
WHERE ROWNUM <= 100Macros
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.
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/$__timeGroupTZor 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:
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:
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:
Example with fill:
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 timeBrace 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:
$__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
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 timeComplex timestamp expressions
Use brace notation for expressions that involve casting or timezone conversion:
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 timeNote
When using timezone-aware macros, use
$__timeFilterTZin theWHEREclause to maintain timezone consistency throughout the query.
Query examples
Monitor CPU usage over time
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 timeCount events per hour with gap filling
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 timeTable query with row limit
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 DESCSupported data types
The plugin supports standard Oracle data types and converts them to Grafana DataFrame types automatically.
The following types are not directly supported and require conversion in your SQL query:
Query limits
Be aware of these limits when writing queries:
Caution
Large result sets consume significant memory on the Grafana server. Use aggregation, time filtering, and
ROWNUMlimits 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:
- Navigate to Explore in the left-side menu.
- Select your Oracle data source from the data source dropdown.
- Write your SQL query in the editor.
- 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:
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 timeSystem statistics (CPU usage, I/O):
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 timeStorage monitoring
Tablespace usage:
SELECT
tablespace_name AS metric,
ROUND(used_percent, 2) AS "Usage %"
FROM DBA_TABLESPACE_USAGE_METRICS
ORDER BY used_percent DESCTablespace growth over time (requires AWR or custom logging):
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 timeSession and connection monitoring
Current sessions by status:
SELECT
status,
COUNT(*) AS count
FROM V$SESSION
WHERE username IS NOT NULL
GROUP BY statusWait events (top 10):
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 ONLYBusiness metrics
Order volume over time:
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 timeSLA compliance (response time percentiles):
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 timeNote
Queries against
V$andDBA_views require the appropriate privileges. Refer to Create a least-privilege database user for permission setup.
Next steps
- Use template variables to create dynamic dashboards.
- Set up alerting based on Oracle queries.
- Create annotations to mark events on your time-series panels.


