使用 Sql_variant 数据类型

下载 JDBC 驱动程序

从版本 6.3.0 开始,JDBC 驱动程序支持 sql_variant 数据类型。 使用表值参数和 BulkCopy 等功能时,也支持 Sql_variant,但有一些限制。 并非所有数据类型都可以存储在 sql_variant 数据类型中。 有关 sql_variant 的受支持数据类型的列表,请参阅 sql_variant (Transact-SQL)

填充和检索表

假设一个表中包含 sql_variant 列,如下所示:

CREATE TABLE sampleTable (col1 sql_variant)

使用语句插入值的示例脚本:

try (Statement stmt = connection.createStatement()){
    stmt.execute("insert into sampleTable values (1)");
}

使用预定义语句插入值:

try (PreparedStatement preparedStatement = con.prepareStatement("insert into sampleTable values (?)")) {
    preparedStatement.setObject(1, 1);
    preparedStatement.execute();
}

如果所传递的数据的基础类型已知,则可以使用相应的资源库。 例如,在插入整数值时,可以使用 preparedStatement.setInt()

try (PreparedStatement preparedStatement = con.prepareStatement("insert into table values (?)")) {
    preparedStatement.setInt (1, 1);
    preparedStatement.execute();
}

若要从表中读取值,可以使用相应的 getter。 例如,如果来自服务器的值已知,则可以使用 getInt()getString() 方法:

try (SQLServerResultSet resultSet = (SQLServerResultSet) stmt.executeQuery("select * from sampleTable ")) {
    resultSet.next();
    resultSet.getInt(1); //or rs.getString(1); or rs.getObject(1);
}

将存储过程和 sql_variant 一起使用

具有如下所示的存储过程:

String sql = "CREATE PROCEDURE " + inputProc + " @p0 sql_variant OUTPUT AS SELECT TOP 1 @p0=col1 FROM sampleTable ";

必须注册输出参数:

try (CallableStatement callableStatement = con.prepareCall(" {call " + inputProc + " (?) }")) {
    callableStatement.registerOutParameter(1, microsoft.sql.Types.SQL_VARIANT);
    callableStatement.execute();
}

sql_variant 限制

  • 当使用 TVP 用存储在 sql_variant 中的 datetime/smalldatetime/date 值填充表时,在 ResultSet 上调用 getDateTime()/getSmallDateTime()/getDate() 将无效,并且会引发以下异常:

    Java.lang.String cannot be cast to java.sql.Timestamp

    解决方法:改为使用 getString()getObject()

  • 使用 TVP 填充表并在 sql_variant 中发送 null 值不受支持。 尝试这样做会导致异常:

    Inserting null value with column type sql_variant in TVP is not supported.

另请参阅

了解 JDBC 驱动程序数据类型