使用基本数据类型

下载 JDBC 驱动程序

Microsoft JDBC Driver for SQL Server 使用 JDBC 基本数据类型将 SQL Server 数据类型转换为 Java 编程语言可以理解的格式,反之亦然。 JDBC 驱动程序支持 JDBC 4.0 API,其中包括 SQLXML 数据类型和区域 (Unicode) 数据类型,如 NCHARNVARCHARLONGNVARCHARNCLOB

数据类型映射

下表列出了基本 SQL Server、JDBC 和 Java 编程语言数据类型之间的默认映射:

SQL Server 类型 JDBC 类型 (java.sql.Types) Java 语言类型
bigint BIGINT long
binary BINARY byte[]
bit BIT boolean
char CHAR String
date DATE java.sql.Date
datetime3 TIMESTAMP java.sql.Timestamp
datetime2 TIMESTAMP java.sql.Timestamp
datetimeoffset2 microsoft.sql.Types.DATETIMEOFFSET microsoft.sql.DateTimeOffset
Decimal DECIMAL java.math.BigDecimal
FLOAT DOUBLE double
image LONGVARBINARY byte[]
int INTEGER int
money DECIMAL java.math.BigDecimal
nchar CHAR

NCHAR (Java SE 6.0)
字符串
ntext LONGVARCHAR

LONGNVARCHAR (Java SE 6.0)
字符串
numeric NUMERIC java.math.BigDecimal
nvarchar VARCHAR

NVARCHAR (Java SE 6.0)
字符串
nvarchar(max) VARCHAR

NVARCHAR (Java SE 6.0)
字符串
real real FLOAT
smalldatetime TIMESTAMP java.sql.Timestamp
smallint SMALLINT short
smallmoney DECIMAL java.math.BigDecimal
text LONGVARCHAR 字符串
time TIME1 java.sql.Time1
timestamp BINARY byte[]
tinyint TINYINT short
udt VARBINARY byte[]
uniqueidentifier CHAR 字符串
varbinary VARBINARY byte[]
varbinary(max) VARBINARY byte[]
varchar VARCHAR 字符串
varchar(max) VARCHAR 字符串
xml LONGVARCHAR

LONGNVARCHAR (Java SE 6.0)
字符串

SQLXML
sqlvariant microsoft.sql.Types.SQL_VARIANT 对象
geometry VARBINARY byte[]
geography VARBINARY byte[]

1 若要将 java.sql.Time 与时间 SQL Server 类型一起使用,必须将 sendTimeAsDatetime 连接属性设置为 false。

2 可以通过编程方式使用 DateTimeOffset 类访问 datetimeoffset 的值。

3 从 SQL Server 2016 开始,java.sql.Timestamp 值不能再用于比较 datetime 列中的值。 此限制是由于以不同方式将 datetime 转换为 datetime2 的服务器端更改,从而产生不相等的值。 此问题的解决方法是将 datetime 列更改为 datetime2(3),使用 String 而不是 java.sql.Timestamp,或将数据库兼容性级别更改为 120 或更低。

以下几部分提供了如何使用 JDBC 驱动程序和基本数据类型的示例。 有关如何在 Java 应用程序中使用基本数据类型的更多详细示例,请参阅基本数据类型示例

以字符串格式检索数据

如果必须从映射到任意 JDBC 基本数据类型的数据源检索数据,并以字符串的格式查看这些数据,或者如果不需要强类型的数据,则可以使用 SQLServerResultSet 类的 getString 方法,如下所示。 下面的示例展示了这种用法:

try(Statement stmt = con.createStatement();) {
    ResultSet rs = stmt.executeQuery("SELECT lname, job_id FROM employee WHERE (lname = 'Brown')");
    rs.next();
    short empJobID = rs.getString("job_id");
}

按数据类型检索数据

如果必须从数据源检索数据,并且已知检索的数据类型,则应使用 SQLServerResultSet 类的任一 get<Type> 方法(也称为 getter 方法)。 通过 get<Type> 方法,可以使用列名或列索引,如下所示:

try(Statement stmt = con.createStatement();) {
    ResultSet rs = stmt.executeQuery("SELECT lname, job_id FROM employee WHERE (lname = 'Brown')");
    rs.next();
    short empJobID = rs.getShort("job_id");
}

注意

使用确定位数的 getUnicodeStream 和 getBigDecimal 方法已遭弃用,不受 JDBC 驱动程序支持。

按数据类型更新数据

如果必须更新数据源中字段的值,请使用 SQLServerResultSet 类的一种 update<Type> 方法。 在下面的示例中,updateInt 方法与 updateRow 方法结合使用,用于更新数据源中的数据:

try (Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);) {
    ResultSet rs = stmt.executeQuery("SELECT lname, job_id FROM employee WHERE (lname = 'Brown')");
    rs.next();
    int empJobID = rs.getInt(2);
    empJobID++;
    rs.first();
    rs.updateInt(2, empJobID);
    rs.updateRow();
}

注意

JDBC Driver 无法更新列名长度超过 127 个字符的 SQL Server 列。 如果尝试更新名称长度超过 127 个字符的列,将引发异常。

通过参数化查询来更新数据

如果通过使用参数化查询来更新数据源中的数据,可以使用 SQLServerPreparedStatement 类的任一 set<Type> 方法来设置参数的数据类型。 这些方法也称为 setter 方法。 在下面的示例中,prepareStatement 方法用于预编译参数化查询,然后在调用 executeUpdate 方法前,使用 setString 方法来设置参数的字符串值。

try(PreparedStatement pstmt = con.prepareStatement("UPDATE employee SET fname = ? WHERE (lname = 'Brown')");) {
    String name = "Bob";
    pstmt.setString(1, name);
    int rowCount = pstmt.executeUpdate();
}

若要详细了解参数化查询,请参阅使用包含参数的 SQL 语句

向存储过程传递参数

如果必须向存储过程传递类型参数,则可使用 SQLServerCallableStatement 类的任一 set<Type> 方法通过索引或名称来设置此参数。 在下面的示例中,prepareCall 方法用于设置对存储过程的调用,然后在调用 executeQuery 方法之前,使用 setString 方法设置调用的参数。

try(CallableStatement cstmt = con.prepareCall("{call employee_jobid(?)}");) {
    String lname = "Brown";
    cstmt.setString(1, lname);
    ResultSet rs = cstmt.executeQuery();
}

注意

在此实例中,将返回一个结果集,包含此存储过程的运行结果。

BigDecimal

使用 BigDecimal 参数值时,精度和小数位数可能会与值一起通过 setBigDecimal 传递。 使用 setBigDecimal 方法可避免潜在的值截断。 或者,如果连接字符串选项 calcBigDecimalPrecision 设置为 true,则驱动程序将以牺牲性能为代价,代表用户计算 BigDecimal 输入的精度。 如果单独传入该值,未设置 calcBigDecimalPrecision,或此选项设置为 false,则驱动程序将假定该 BigDecimal 值为最大允许精度值 (38)。

若要详细了解结合使用 JDBC 驱动程序与存储过程和输入参数,请参阅使用包含输入参数的存储过程

从存储过程检索参数

如果必须从存储过程检索参数,则必须先使用 SQLServerCallableStatement 类的 registerOutParameter 方法通过名称或索引注册一个 out 参数。 然后在调用存储过程后,将返回的输出参数分配给合适的变量。 在下面的示例中,使用 prepareCall 方法设置对存储过程的调用,使用 registerOutParameter 方法设置 out 参数,然后在调用 executeQuery 方法前,使用 setString 方法设置调用的参数。 使用 getShort 方法来检索存储过程的 out 参数的值。

try(CallableStatement cstmt = con.prepareCall("{call employee_jobid (?, ?)}");) {
    cstmt.registerOutParameter(2, java.sql.Types.SMALLINT);
    String lname = "Brown";
    cstmt.setString(1, lname);
    ResultSet rs = cstmt.executeQuery();
    short empJobID = cstmt.getShort(2);
}

注意

除返回的输出参数外,还可能返回一个结果集,包含此存储过程的运行结果。

若要详细了解结合使用 JDBC 驱动程序与存储过程和输出参数,请参阅使用包含输出参数的存储过程

另请参阅

了解 JDBC 驱动程序数据类型