0

I have a stored procedure in my SQL Server that take an argument of TVP type. After my finding I need to use SQLServerPreparedStatement to pass TVP in SP.

Application Tech Stack

  • Spring Boot
  • Java 11
  • SQL Server
  • Wildfly Server 21.0.1
  • JNDI Data Source
  • JDBCTemplate

Problem statement When I lookup for JNDI data source it given me an object of WildflyDataSource class, that is wrapped. I cannot cast or unwrap it in others. Even the connection it provide is also wrapped. so when I get the PrepareStatement or CallableStatement from connection I could not cast or unwrape it to SQLServerPreparedStatement.

Sample Code 1

MyTVP sourceRecords = new MyTVP(ListId);
SQLServerPreparedStatement pStmt = jdbcTemplate.getDataSource().getConnection()
                                    .prepareStatement("{call dbo.del ( ?)}")
                                    .unwrap(SQLServerPreparedStatement.class);
pStmt.setStructured(1, "dbo.MyTVP", sourceRecords);
pStmt.execute();

Sample Code 2

List<SqlParameter> paramList = new ArrayList<>();
paramList.add(new SqlParameter(Types.OTHER));
LList sourceRecords = new LList(ListId);
bpJdbcTemplate.call(new CallableStatementCreator() {
    @Override
    public CallableStatement createCallableStatement(Connection con) throws SQLException {
        CallableStatement callableStatement = con.prepareCall("{call dbo.del (?)}");
        callableStatement.setObject(1, sourceRecords);
        return callableStatement;
    }
}, paramList);

Common Code

Long ListId = 45L;
import com.microsoft.sqlserver.jdbc.ISQLServerDataRecord;

class LList implements ISQLServerDataRecord {

    int currentRow = 0;
    Object[] row = new Object[1];

    public LList(Long v) {
        this.row[0] = v;
    }

    @Override
    public SQLServerMetaData getColumnMetaData(int i) {
        // Return the column metadata.
        if (1 == i)
            return new SQLServerMetaData("BigIntValue", Types.BIGINT);
        return null;
    }

    @Override
    public int getColumnCount() {
        return 1;
    }

    @Override
    public Object[] getRowData() {
        return row;
    }

    @Override
    public boolean next() {
        currentRow++;
        if (1 == currentRow)
            return true;
        else
            return false;
    }
}

When I execute the above code I got the below exceptions

ERROR [stderr] (default task-1) java.sql.SQLException: IJ031030: Not a wrapper for: com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement
ERROR [stderr] (default task-1)     at org.jboss.ironjacamar.jdbcadapters@1.4.23.Final//org.jboss.jca.adapters.jdbc.JBossWrapper.unwrap(JBossWrapper.java:96)
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException; SQL state [null]; error code [0]; The conversion from UNKNOWN to UNKNOWN is unsupported.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The conversion from UNKNOWN to UNKNOWN is unsupported.

Please let me know how I can achieve calling SP with TVP?

  • Can this help you? https://stackoverflow.com/questions/22657097/freeing-wrapped-connection-in-jboss-7-2 You should probably unwrap the Connection to SQLServerConnection and create prepared statement from it since JBoss doesn't expose unwrapped PreparedStatements – siggemannen Jan 20 '23 at 20:15

0 Answers0