Wrong fixes and their failure modes
The number that matters is -155. It is the SQL Server JDBC type code associated with DATETIMEOFFSET, and the Ignition gateway rejects that result-set type with java.sql.SQLException: Unknown SQL type: -155. This is a data-type translation failure, not a bad timestamp or a query timeout.
| Attempt | Why it fails or creates another problem | Preferred action |
|---|---|---|
Cast DATETIMEOFFSET directly to datetime2
|
The cast removes the offset metadata but does not normalize the value to UTC. The displayed clock time can therefore acquire the wrong meaning. | Convert to the required zone first, then cast to a gateway-compatible type. |
Replace every offset column with datetime
|
This avoids type -155 but permanently removes the stored offset. It is a schema decision, not merely a query workaround. |
Use UTC datetime only when the application has deliberately standardized on UTC storage. |
Apply fixed DATEADD corrections such as five hours |
A fixed difference fails when a requested interval crosses a daylight-saving transition. | Use AT TIME ZONE to calculate each boundary. |
Convert the timestamp column inside WHERE
|
Wrapping an indexed time-series column in conversion functions can prevent an efficient index seek and force row-by-row work. | Convert the boundary constants and compare them with the bare column. |
| Change only the Java runtime | The observed installation already reached SQL Server through Java; failure occurred while translating returned column metadata. | Test the driver, gateway translator, and query projection as separate layers. |
Type-translation mechanism
The affected installation ran Ignition 8.0.5 (b2019101516) on Azul Systems Java 11.0.4. Any query returning one of the database's DATETIMEOFFSET columns produced the gateway exception. A query can execute successfully in SQL Server and still fail when the gateway reads its result metadata and tries to map every SQL value into a Java or Ignition data type.
The failure boundary matters. If selecting ordinary columns works but adding the offset column produces -155, database connectivity, credentials, and basic SQL syntax are already functioning. The result projection is exposing a type that this gateway path cannot translate.
| Quantity or token | Meaning | Where to read it |
|---|---|---|
-155 |
Returned SQL type rejected by the JDBC-to-gateway translation path | Gateway exception and SQL exception chain |
8.0.5 (b2019101516) |
Affected Ignition build in this installation | Gateway version information |
11.0.4 |
Java runtime used when the fault occurred | Gateway system information |
nvarchar(30) |
Compatible text projection large enough for the demonstrated timestamp and offset representation | SQL query projection |
SQL Server 2016 or later |
Required for the demonstrated AT TIME ZONE approach |
SQL Server version |
Diagnostic boundary checks
- Run a minimal query that selects a non-time column from an affected table. This confirms the connection and table access without invoking offset translation.
- Add the
DATETIMEOFFSETcolumn unchanged. Reproduction ofUnknown SQL type: -155isolates the failure to the returned type. - Project that same value with
CAST(... AS nvarchar(30)). A successful result confirms that SQL Server can read the data and that a compatible projection crosses the gateway boundary. - Inspect the actual column type rather than relying on its name. A column named
StartTimeUTCmay bedatetime,datetime2, orDATETIMEOFFSET; each requires different offset handling. - Decide whether the consumer needs display text, a typed timestamp, or only time filtering. Text is suitable for display and transport, while filtering and arithmetic should remain typed inside SQL Server.
Also record the JDBC driver identity from the gateway connection configuration. A later gateway or driver combination may add the missing mapping, but compatibility must be verified with the actual connection rather than inferred from the Java version.
Compatible projection procedure
For display-only results, perform timezone calculation in SQL Server and return text to Ignition. When the stored column is a UTC datetime without offset metadata, attach UTC first, convert to the target zone second, and cast last:
SELECT CAST(
StartTimeUTC AT TIME ZONE 'UTC'
AT TIME ZONE 'EASTERN STANDARD TIME'
AS nvarchar(30)
) AS LocalTimeText
FROM SourceTable;
AT TIME ZONE 'UTC' labels the stored clock value as UTC. The second operation calculates the Eastern offset for that instant, including daylight-saving behavior, and nvarchar(30) prevents type -155 from reaching the gateway.
If the source is already DATETIMEOFFSET, omit the first attachment step and convert the existing instant directly to the target zone before casting. Attaching 'UTC' to an already offset-aware value would reinterpret its clock fields instead of merely preserving its instant.
For a typed UTC result rather than display text, convert the value to UTC with SWITCHOFFSET or AT TIME ZONE, then cast to a supported non-offset type. That final cast intentionally drops offset metadata, so the column alias and application contract must state that the returned clock value is UTC.
Sargable UTC filtering
This is heat in the database engine, not gateway logic. Converting every timestamp row consumes CPU and can defeat an index on the time column. Convert the small set of boundary values instead, then compare those values with the unmodified column.
For a UTC datetime column and local Eastern boundary values supplied as parameters, use this shape:
WHERE StartTimeUTC >= CONVERT(datetime,
CAST(? AS datetime2)
AT TIME ZONE 'EASTERN STANDARD TIME'
AT TIME ZONE 'UTC')
AND StartTimeUTC < CONVERT(datetime,
CAST(? AS datetime2)
AT TIME ZONE 'EASTERN STANDARD TIME'
AT TIME ZONE 'UTC')
The half-open interval includes the start and excludes the end, preventing adjacent shifts from counting the same boundary record twice. Calculate the start and end independently: an interval that crosses a daylight-saving change may span a different number of elapsed hours than the wall-clock schedule suggests.
GETDATE() supplies a clock value without timezone metadata, while GETUTCDATE() supplies a UTC clock value without an offset-bearing type. Attach the intended zone explicitly before conversion. Fixed subtraction based on the current offset fails when one boundary is on standard time and the other is on daylight time.
If part of a predicate cannot avoid a function on the stored timestamp, first use a subquery to prefilter rows with the sargable UTC range. Apply the more complex condition only to that reduced result set.
Verification criteria
- Confirm that the gateway receives the projected column without
Unknown SQL type: -155. - Test an ordinary timestamp and timestamps around the daylight-saving boundary. For the demonstrated Eastern conversion,
2018-03-11 07:00:00UTC maps to2018-03-11 03:00:00.000 -04:00. - Check that the returned text retains the date, time, fractional seconds, and offset when
nvarchar(30)is used. - Compare row counts at two adjacent shift boundaries. A half-open range must produce neither a duplicate boundary row nor a gap.
- Inspect the SQL Server execution plan. The time predicate should reference the bare timestamp column so an applicable index can be considered for a seek.
Keep timezone conversion out of the stored column side of the predicate even when a small test appears fast. Time-series cost grows with candidate rows, and a conversion that scans a short interval can become the dominant load over longer retention periods.
FAQ
What happens if I cast DATETIMEOFFSET to datetime2?
The offset is discarded, but the clock fields are not automatically converted to UTC. Convert to 'UTC' first if the resulting datetime2 value will be treated as UTC.
What happens if a query crosses daylight-saving time?
A fixed-hour correction can make the interval one hour short or long. Calculate both local boundaries with AT TIME ZONE 'EASTERN STANDARD TIME', convert each to UTC, and compare those constants with the bare UTC column.
What happens if type -155 remains after casting the result?
Stop when a minimal CAST(... AS nvarchar(30)) query still returns -155, or when the application requires a native offset-aware value that the configured gateway and driver cannot expose. Capture the minimal query, gateway build 8.0.5 (b2019101516), Java 11.0.4, JDBC driver identity, and full exception chain, then escalate through Ignition's official support channel.