Como usar o tipo de dados sql_variant
Da versão 6.3.0 em diante, o driver JDBC será compatível com o tipo de dados sql_variant. O sql_variant também tem suporte ao usar recursos, como Parâmetros com Valor de Tabela e Cópia em Massa, com algumas limitações. Nem todos os tipos de dados podem ser armazenados no tipo de dados sql_variant. Para obter uma lista de tipos de dados compatíveis com o sql_variant, confira sql_variant (Transact-SQL).
Como preencher e recuperar uma tabela
Supondo que haja uma tabela com uma coluna sql_variant como:
CREATE TABLE sampleTable (col1 sql_variant)
Um script de exemplo para inserir valores usando a instrução:
try (Statement stmt = connection.createStatement()){
stmt.execute("insert into sampleTable values (1)");
}
Inserindo um valor usando a instrução preparada:
try (PreparedStatement preparedStatement = con.prepareStatement("insert into sampleTable values (?)")) {
preparedStatement.setObject(1, 1);
preparedStatement.execute();
}
Se o tipo subjacente dos dados que estão sendo passados for conhecido, o respectivo setter poderá ser usado. Por exemplo, preparedStatement.setInt()
pode ser usado ao inserir um valor inteiro.
try (PreparedStatement preparedStatement = con.prepareStatement("insert into table values (?)")) {
preparedStatement.setInt (1, 1);
preparedStatement.execute();
}
Para ler valores da tabela, os respectivos getters podem ser usados. Por exemplo, os métodos getInt()
ou getString()
poderão ser usados se os valores provenientes do servidor forem conhecidos:
try (SQLServerResultSet resultSet = (SQLServerResultSet) stmt.executeQuery("select * from sampleTable ")) {
resultSet.next();
resultSet.getInt(1); //or rs.getString(1); or rs.getObject(1);
}
Como usar procedimentos armazenados com o sql_variant
Tendo um procedimento armazenado, como:
String sql = "CREATE PROCEDURE " + inputProc + " @p0 sql_variant OUTPUT AS SELECT TOP 1 @p0=col1 FROM sampleTable ";
Os parâmetros de saída devem ser registrados:
try (CallableStatement callableStatement = con.prepareCall(" {call " + inputProc + " (?) }")) {
callableStatement.registerOutParameter(1, microsoft.sql.Types.SQL_VARIANT);
callableStatement.execute();
}
Limitações do sql_variant
Ao usar o TVP para preencher uma tabela com um valor
datetime
/smalldatetime
/date
armazenado em um sql_variant, executar uma chamada aogetDateTime()
/getSmallDateTime()
/getDate()
em um ResultSet não vai funcionar. Além disso, a seguinte exceção será gerada:Java.lang.String cannot be cast to java.sql.Timestamp
Solução alternativa: use
getString()
ougetObject()
.Não há suporte para usar o TVP a fim de preencher uma tabela e enviar um valor nulo a um sql_variant. Tentar fazer isso resultará em uma exceção:
Inserting null value with column type sql_variant in TVP is not supported.