SQL Server Type Support
Foundations JDBC provides comprehensive support for SQL Server data types, including geography, geometry, hierarchyid, and Unicode types.
Key Differences
- TINYINT is UNSIGNED in SQL Server (0-255), unlike most other databases
- Separate Unicode types (NCHAR, NVARCHAR, NTEXT) vs non-Unicode
- DATETIMEOFFSET for timezone-aware timestamps
- UNIQUEIDENTIFIER for UUIDs/GUIDs
- No native array support - use table-valued parameters instead
Integer Types
| SQL Server Type | Java Type | Range | Notes |
|---|---|---|---|
TINYINT | Uint1 | 0-255 | Unsigned! |
SMALLINT | Short | -32,768 to 32,767 | |
INT | Integer | -2^31 to 2^31-1 | |
BIGINT | Long | -2^63 to 2^63-1 |
- Kotlin
- Java
- Scala
val tinyType: SqlServerType<Uint1> = SqlServerTypes.tinyint // Note: unsigned!
val intType: SqlServerType<Int> = SqlServerTypes.int_
val bigType: SqlServerType<Long> = SqlServerTypes.bigint
SqlServerType<Uint1> tinyType = SqlServerTypes.tinyint; // Note: unsigned!
SqlServerType<Integer> intType = SqlServerTypes.int_;
SqlServerType<Long> bigType = SqlServerTypes.bigint;
val tinyType: SqlServerType[Uint1] = SqlServerTypes.tinyint // Note: unsigned!
val intType: SqlServerType[Int] = SqlServerTypes.int_
val bigType: SqlServerType[Long] = SqlServerTypes.bigint
Fixed-Point Types
| SQL Server Type | Java Type | Notes |
|---|---|---|
DECIMAL(p,s) | BigDecimal | Exact numeric |
NUMERIC(p,s) | BigDecimal | Alias for DECIMAL |
MONEY | BigDecimal | Currency (4 decimal places) |
SMALLMONEY | BigDecimal | Smaller currency range |
- Kotlin
- Java
- Scala
val decimalType: SqlServerType<BigDecimal> = SqlServerTypes.decimal
val precise: SqlServerType<BigDecimal> = SqlServerTypes.decimal(18, 4)
val moneyType: SqlServerType<BigDecimal> = SqlServerTypes.money
SqlServerType<BigDecimal> decimalType = SqlServerTypes.decimal;
SqlServerType<BigDecimal> precise = SqlServerTypes.decimal(18, 4);
SqlServerType<BigDecimal> moneyType = SqlServerTypes.money;
val decimalType: SqlServerType[BigDecimal] = SqlServerTypes.decimal
val precise: SqlServerType[BigDecimal] = SqlServerTypes.decimal(18, 4)
val moneyType: SqlServerType[BigDecimal] = SqlServerTypes.money
Floating-Point Types
| SQL Server Type | Java Type | Notes |
|---|---|---|
REAL | Float | 32-bit IEEE 754 |
FLOAT | Double | 64-bit IEEE 754 |
- Kotlin
- Java
- Scala
val realType: SqlServerType<Float> = SqlServerTypes.real
val floatType: SqlServerType<Double> = SqlServerTypes.float_
SqlServerType<Float> realType = SqlServerTypes.real;
SqlServerType<Double> floatType = SqlServerTypes.float_;
val realType: SqlServerType[Float] = SqlServerTypes.real
val floatType: SqlServerType[Double] = SqlServerTypes.float_
Boolean Type
| SQL Server Type | Java Type |
|---|---|
BIT | Boolean |
- Kotlin
- Java
- Scala
val bitType: SqlServerType<Boolean> = SqlServerTypes.bit
SqlServerType<Boolean> bitType = SqlServerTypes.bit;
val bitType: SqlServerType[Boolean] = SqlServerTypes.bit
String Types (Non-Unicode)
| SQL Server Type | Java Type | Max Length | Notes |
|---|---|---|---|
CHAR(n) | String | 8,000 chars | Fixed-length |
VARCHAR(n) | String | 8,000 chars | Variable-length |
VARCHAR(MAX) | String | 2 GB | Large variable-length |
TEXT | String | 2 GB | Deprecated, use VARCHAR(MAX) |
- Kotlin
- Java
- Scala
val charType: SqlServerType<String> = SqlServerTypes.char_(10)
val varcharType: SqlServerType<String> = SqlServerTypes.varchar(255)
val varcharMax: SqlServerType<String> = SqlServerTypes.varcharMax
SqlServerType<String> charType = SqlServerTypes.char_(10);
SqlServerType<String> varcharType = SqlServerTypes.varchar(255);
SqlServerType<String> varcharMax = SqlServerTypes.varcharMax;
val charType: SqlServerType[String] = SqlServerTypes.char_(10)
val varcharType: SqlServerType[String] = SqlServerTypes.varchar(255)
val varcharMax: SqlServerType[String] = SqlServerTypes.varcharMax
String Types (Unicode)
| SQL Server Type | Java Type | Max Length | Notes |
|---|---|---|---|
NCHAR(n) | String | 4,000 chars | Fixed-length Unicode |
NVARCHAR(n) | String | 4,000 chars | Variable-length Unicode |
NVARCHAR(MAX) | String | 2 GB | Large Unicode |
NTEXT | String | 2 GB | Deprecated |
- Kotlin
- Java
- Scala
val ncharType: SqlServerType<String> = SqlServerTypes.nchar(10)
val nvarcharType: SqlServerType<String> = SqlServerTypes.nvarchar(255)
val nvarcharMax: SqlServerType<String> = SqlServerTypes.nvarcharMax
SqlServerType<String> ncharType = SqlServerTypes.nchar(10);
SqlServerType<String> nvarcharType = SqlServerTypes.nvarchar(255);
SqlServerType<String> nvarcharMax = SqlServerTypes.nvarcharMax;
val ncharType: SqlServerType[String] = SqlServerTypes.nchar(10)
val nvarcharType: SqlServerType[String] = SqlServerTypes.nvarchar(255)
val nvarcharMax: SqlServerType[String] = SqlServerTypes.nvarcharMax
Binary Types
| SQL Server Type | Java Type | Max Length |
|---|---|---|
BINARY(n) | byte[] | 8,000 bytes |
VARBINARY(n) | byte[] | 8,000 bytes |
VARBINARY(MAX) | byte[] | 2 GB |
IMAGE | byte[] | 2 GB (deprecated) |
- Kotlin
- Java
- Scala
val binaryType: SqlServerType<ByteArray> = SqlServerTypes.binary(16)
val varbinaryType: SqlServerType<ByteArray> = SqlServerTypes.varbinary(255)
val varbinaryMax: SqlServerType<ByteArray> = SqlServerTypes.varbinaryMax
SqlServerType<byte[]> binaryType = SqlServerTypes.binary(16);
SqlServerType<byte[]> varbinaryType = SqlServerTypes.varbinary(255);
SqlServerType<byte[]> varbinaryMax = SqlServerTypes.varbinaryMax;
val binaryType: SqlServerType[Array[Byte]] = SqlServerTypes.binary(16)
val varbinaryType: SqlServerType[Array[Byte]] = SqlServerTypes.varbinary(255)
val varbinaryMax: SqlServerType[Array[Byte]] = SqlServerTypes.varbinaryMax
Date/Time Types
| SQL Server Type | Java Type | Precision | Notes |
|---|---|---|---|
DATE | LocalDate | Day | Date only |
TIME | LocalTime | 100ns | Time only |
DATETIME | LocalDateTime | 3.33ms | Legacy |
SMALLDATETIME | LocalDateTime | Minute | Legacy |
DATETIME2 | LocalDateTime | 100ns | Modern |
DATETIMEOFFSET | OffsetDateTime | 100ns | With timezone |
- Kotlin
- Java
- Scala
val dateType: SqlServerType<LocalDate> = SqlServerTypes.date
val timeType: SqlServerType<LocalTime> = SqlServerTypes.time
val time3: SqlServerType<LocalTime> = SqlServerTypes.time(3) // TIME(3)
// Legacy types
val datetimeType: SqlServerType<LocalDateTime> = SqlServerTypes.datetime
val smalldtType: SqlServerType<LocalDateTime> = SqlServerTypes.smalldatetime
// Modern types (recommended)
val datetime2Type: SqlServerType<LocalDateTime> = SqlServerTypes.datetime2
val datetime2_3: SqlServerType<LocalDateTime> = SqlServerTypes.datetime2(3)
// Timezone-aware
val dtoType: SqlServerType<OffsetDateTime> = SqlServerTypes.datetimeoffset
val dto3: SqlServerType<OffsetDateTime> = SqlServerTypes.datetimeoffset(3)
SqlServerType<LocalDate> dateType = SqlServerTypes.date;
SqlServerType<LocalTime> timeType = SqlServerTypes.time;
SqlServerType<LocalTime> time3 = SqlServerTypes.time(3); // TIME(3)
// Legacy types
SqlServerType<LocalDateTime> datetimeType = SqlServerTypes.datetime;
SqlServerType<LocalDateTime> smalldtType = SqlServerTypes.smalldatetime;
// Modern types (recommended)
SqlServerType<LocalDateTime> datetime2Type = SqlServerTypes.datetime2;
SqlServerType<LocalDateTime> datetime2_3 = SqlServerTypes.datetime2(3);
// Timezone-aware
SqlServerType<OffsetDateTime> dtoType = SqlServerTypes.datetimeoffset;
SqlServerType<OffsetDateTime> dto3 = SqlServerTypes.datetimeoffset(3);
val dateType: SqlServerType[LocalDate] = SqlServerTypes.date
val timeType: SqlServerType[LocalTime] = SqlServerTypes.time
val time3: SqlServerType[LocalTime] = SqlServerTypes.time(3) // TIME(3)
// Legacy types
val datetimeType: SqlServerType[LocalDateTime] = SqlServerTypes.datetime
val smalldtType: SqlServerType[LocalDateTime] = SqlServerTypes.smalldatetime
// Modern types (recommended)
val datetime2Type: SqlServerType[LocalDateTime] = SqlServerTypes.datetime2
val datetime2_3: SqlServerType[LocalDateTime] = SqlServerTypes.datetime2(3)
// Timezone-aware
val dtoType: SqlServerType[OffsetDateTime] = SqlServerTypes.datetimeoffset
val dto3: SqlServerType[OffsetDateTime] = SqlServerTypes.datetimeoffset(3)
UNIQUEIDENTIFIER (UUID/GUID)
| SQL Server Type | Java Type |
|---|---|
UNIQUEIDENTIFIER | java.util.UUID |
- Kotlin
- Java
- Scala
val uuidType: SqlServerType<UUID> = SqlServerTypes.uniqueidentifier
SqlServerType<UUID> uuidType = SqlServerTypes.uniqueidentifier;
val uuidType: SqlServerType[UUID] = SqlServerTypes.uniqueidentifier
XML Type
| SQL Server Type | Java Type |
|---|---|
XML | Xml |
- Kotlin
- Java
- Scala
val xmlType: SqlServerType<Xml> = SqlServerTypes.xml
SqlServerType<Xml> xmlType = SqlServerTypes.xml;
val xmlType: SqlServerType[Xml] = SqlServerTypes.xml
JSON Type
SQL Server 2016+ stores JSON as NVARCHAR(MAX):
| SQL Server Type | Java Type | Notes |
|---|---|---|
NVARCHAR(MAX) | Json | JSON stored as Unicode string |
- Kotlin
- Java
- Scala
val jsonType: SqlServerType<Json> = SqlServerTypes.json
SqlServerType<Json> jsonType = SqlServerTypes.json;
val jsonType: SqlServerType[Json] = SqlServerTypes.json
Spatial Types
SQL Server spatial types use the JDBC driver's native classes:
| SQL Server Type | Java Type | Notes |
|---|---|---|
GEOGRAPHY | Geography | Geodetic (round earth) |
GEOMETRY | Geometry | Planar (flat earth) |
- Kotlin
- Java
- Scala
val geoType: SqlServerType<Geography> = SqlServerTypes.geography
val geomType: SqlServerType<Geometry> = SqlServerTypes.geometry
SqlServerType<Geography> geoType = SqlServerTypes.geography;
SqlServerType<Geometry> geomType = SqlServerTypes.geometry;
val geoType: SqlServerType[Geography] = SqlServerTypes.geography
val geomType: SqlServerType[Geometry] = SqlServerTypes.geometry
HIERARCHYID
For hierarchical tree structures:
| SQL Server Type | Java Type | Notes |
|---|---|---|
HIERARCHYID | HierarchyId | Path notation like /1/2/3/ |
- Kotlin
- Java
- Scala
val hierarchyType: SqlServerType<HierarchyId> = SqlServerTypes.hierarchyid
SqlServerType<HierarchyId> hierarchyType = SqlServerTypes.hierarchyid;
val hierarchyType: SqlServerType[HierarchyId] = SqlServerTypes.hierarchyid
ROWVERSION / TIMESTAMP
| SQL Server Type | Java Type | Notes |
|---|---|---|
ROWVERSION | byte[] | 8-byte version number |
TIMESTAMP | byte[] | Alias for ROWVERSION |
- Kotlin
- Java
- Scala
val rowversionType: SqlServerType<ByteArray> = SqlServerTypes.rowversion
SqlServerType<byte[]> rowversionType = SqlServerTypes.rowversion;
val rowversionType: SqlServerType[Array[Byte]] = SqlServerTypes.rowversion
SQL_VARIANT
| SQL Server Type | Java Type | Notes |
|---|---|---|
SQL_VARIANT | Object | Can store various types |
- Kotlin
- Java
- Scala
val variantType: SqlServerType<Any> = SqlServerTypes.sqlVariant
SqlServerType<Object> variantType = SqlServerTypes.sqlVariant;
val variantType: SqlServerType[Object] = SqlServerTypes.sqlVariant
VECTOR (SQL Server 2025)
| SQL Server Type | Java Type | Notes |
|---|---|---|
VECTOR | byte[] | For embeddings/ML |
- Kotlin
- Java
- Scala
val vectorType: SqlServerType<ByteArray> = SqlServerTypes.vector
SqlServerType<byte[]> vectorType = SqlServerTypes.vector;
val vectorType: SqlServerType[Array[Byte]] = SqlServerTypes.vector
Nullable Types
Any type can be made nullable using .opt():
- Kotlin
- Java
- Scala
val notNull: SqlServerType<Int> = SqlServerTypes.int_
val nullable: SqlServerType<Int?> = SqlServerTypes.int_.opt()
SqlServerType<Integer> notNull = SqlServerTypes.int_;
SqlServerType<Optional<Integer>> nullable = SqlServerTypes.int_.opt();
val notNull: SqlServerType[Int] = SqlServerTypes.int_
val nullable: SqlServerType[Option[Int]] = SqlServerTypes.int_.opt
Custom Domain Types
Wrap base types with custom Java types using transform:
- Kotlin
- Java
- Scala
// Wrapper type
data class OrderId(val value: Int)
// Create SqlServerType from INT
val orderIdType: SqlServerType<OrderId> =
SqlServerTypes.int_.transform(::OrderId, OrderId::value)
// Wrapper type
public record OrderId(Integer value) {}
// Create SqlServerType from INT
SqlServerType<OrderId> orderIdType =
SqlServerTypes.int_.transform(OrderId::new, OrderId::value);
// Wrapper type
case class OrderId(value: Int)
// Create SqlServerType from INT
val orderIdType: SqlServerType[OrderId] =
SqlServerTypes.int_.transform(OrderId.apply, _.value)