Как передать табличный параметр в хранимую процедуру, используя jTDS? - PullRequest
0 голосов
/ 03 января 2019

Мне нужно вызвать хранимую процедуру, используя драйвер JTDS jdbc.

Но эта хранимая процедура нуждается в типе структуры в качестве параметра. Jtds CallableStatement не имеет метода, который устанавливает структуру, поэтому я попытался привести к SQLServerCallableStatement и установить желаемую структуру. Код, который я использую ниже

            Connection con = ds.getConnection();
            CallableStatement call = con.prepareCall("{call getErrosSKF ?,?,?,?}");
            call.setString("agrupador", agrupador);
            call.setDate(2, new Date(dataInicio.getTimeInMillis()));
            call.setDate(3, new Date(dataFim.getTimeInMillis()));   

            SQLServerDataTable areas = new SQLServerDataTable();
            areas.addColumnMetadata("id",Types.INTEGER);
            for(Integer a : skfIdAreas) {
                areas.addRow(a);
            }
             // generate an exception
            ((SQLServerCallableStatement) call).setStructured(4, "erroSKFTable", areas);

Но я не могу разыграть, потому что генерируется исключение, говорящее, что JtdsCallableStatement нельзя привести к SqlServerCallableStatemen.

Есть ли альтернатива, которую я могу использовать?

1 Ответ

0 голосов
/ 03 января 2019

Поддержка табличных параметров (TVP) - сравнительно недавнее дополнение к драйверу JDBC от Microsoft для SQL Server, и фактически, согласно ...

Системные требования для драйвера JDBC

... ни один из доступных на данный момент драйверов JDBC от Microsoft не будет работать с JRE_6.Вы можете попытаться найти древний драйвер JDBC от Microsoft, но он все равно не будет напрямую поддерживать TVP, поэтому вы можете также придерживаться jTDS.

Теперь jTDS напрямую не поддерживаетTVP, но вы можете выполнить свою задачу, создав

  1. временную таблицу,
  2. , заполнив временную таблицу своими данными, а затем
  3. , используя анонимный кодблокировать заполнение TVP из временной таблицы и затем вызывать хранимую процедуру.

Пример:

Учитывая существующую справочную таблицу с именем [фонетическая] ...

letter  word
------  -------
A       Alfa
B       Bravo
C       Charlie
...
Y       Yankee
Z       Zulu

... определенный пользователем тип таблицы ...

CREATE TYPE [dbo].[LetterListTableType] AS TABLE(
    [seq] [int] NOT NULL,
    [letter] [varchar](1) NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [seq] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)

... и хранимая процедура, которая принимает этот тип таблицы в качестве параметра ...

CREATE PROCEDURE [dbo].[GetPhonetic] 
    @letters dbo.LetterListTableType READONLY
AS
BEGIN
    SET NOCOUNT ON;
    SELECT l.seq, l.letter, p.word 
        FROM phonetic p INNER JOIN @letters l on p.letter = l.letter
        ORDER BY l.seq;
END

... следующий код Java ...

// 0. create some test data
String[] letters = new String[] { "G", "o", "r", "d" };
//
// 1. create temporary table
Statement s = conn.createStatement();
s.executeUpdate("CREATE TABLE #tmp (seq INT IDENTITY PRIMARY KEY, letter VARCHAR(1))");
//
// 2. populate temporary table with letters to look up
PreparedStatement ps = conn.prepareStatement("INSERT INTO #tmp (letter) VALUES (?)");
for (String letter : letters) {
    ps.setString(1, letter);
    ps.addBatch();
}
ps.executeBatch();
//
// 3. use anonymous code block to pass table-valued parameter to stored procedure
String sql = 
          "SET NOCOUNT ON; "
        + "DECLARE @tvp dbo.LetterListTableType; "
        + "INSERT INTO @tvp (seq, letter) SELECT seq, letter FROM #tmp; "
        + "EXEC dbo.GetPhonetic @tvp; ";
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
    System.out.printf("%s -> %s%n", rs.getString("letter"), rs.getString("word"));
}

... производит

G -> Golf
o -> Oscar
r -> Romeo
d -> Delta
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...