2009-11-11 2 views
1

Я использую Spring JdbcTemplate, и я застреваю в точке, где у меня есть запрос, который обновляет столбец, который на самом деле является массивом int. База данных - это postgres 8.3.7. Это код, я использую:Как обновить столбец массива postgresql с помощью Spring JdbcTemplate?

public int setUsersArray(int idUser, int idDevice, Collection<Integer> ids) { 

    int update = -666; 

    int[] tipi = new int[3]; 
    tipi[0] = java.sql.Types.INTEGER; 
    tipi[1] = java.sql.Types.INTEGER; 
    tipi[2] = java.sql.Types.ARRAY; 

    try { 
     update = this.jdbcTemplate.update(setUsersArrayQuery, new Object[] { 
       ids, idUser, idDevice }, tipi); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return update; 
} 

Этот запрос "обновление table_name набор array_column = где id_user = и id_device =??". я получаю это исключение:

org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [обновление acotel_msp.users_mau set denied_sub_client =? где id_users =? и id_mau =?]; Индекс столбца выходит за пределы диапазона: 4, количество столбцов: 3; Вложенное исключение - org.postgresql.util.PSQLException: индекс столбца вне диапазона: 4, количество столбцов: 3.

Вызвано: org.postgresql.util.PSQLException: индекс столбца выходит за пределы допустимого диапазона: 4, количество колонок: 3.

Я просмотрел документы весны jdbc, но я не могу найти никакой помощи, я буду продолжать искать, так или иначе кто-нибудь может указать мне в правильном направлении? Благодаря!

EDIT:

Очевидно, что порядок был неправ, моя вина ...

Я попробовал оба ваши решения, в первом случае я имел это:

org.springframework.jdbc.BadSqlGrammarException : PreparedStatementCallback; плохая грамматика SQL [обновление пользователей установлено denied_sub_client =? где id_users =? и id_device =?]; вложенное исключение org.postgresql.util.PSQLException: Невозможно привести экземпляр java.util.ArrayList к типу Types.ARRAY

Попытка второе решение, которое я имел это:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; плохая грамматика SQL [обновление пользователей установлено denied_sub_client =? где id_users =? и id_device =?]; Вложенное исключение - org.postgresql.util.PSQLException: не может использовать экземпляр [Ljava.lang.Object; для типа Types.ARRAY

Я полагаю, мне нужен экземпляр java.sql.Array, но как его создать с помощью JdbcTemplate?

ответ

1

Тип аргумента и аргумент не соответствуют.

попробуйте поменять тип аргумента

int[] tipi = new int[3]; 
tipi[0] = java.sql.Types.ARRAY; 
tipi[1] = java.sql.Types.INTEGER; 
tipi[2] = java.sql.Types.INTEGER; 

или использовать

update = this.jdbcTemplate.update(setUsersArrayQuery, new Object[] { 
           ids.toArray(), idUser, idDevice }) 

и посмотреть, если он работает

+0

Я отредактировал мой ответ, я пытался как ваш решения, я полагаю, мне нужен экземпляр java.sql.Array, но как его создать с помощью JdbcTemplate? – Francesco

1

http://valgogtech.blogspot.com/2009/02/passing-arrays-to-postgresql-database.html объясняет, как создать java.sql.Array PostgreSQL в основном Array. getBaseTypeName должен возвращать int и Array.toString должен возвращать содержимое массива в формате «{1,2,3}»

после того, как вы создадите массив, вы можете установить его с помощью createdstatement.setArray (...) из PreparedStatementCreator, например.

jdbcTemplate.update(
    new PreparedStatementCreator() { 
     public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { 

Good Luck ..

2
private static final String ARRAY_DATATYPE = "int4"; 
private static final String SQL_UPDATE = "UPDATE foo SET arr = ? WHERE d = ?"; 
final Integer[] existing = ...; 
final DateTime dt = ...; 

getJdbcTemplate().update(new PreparedStatementCreator() { 
    @Override 
    public PreparedStatement createPreparedStatement(final Connection con) throws SQLException { 
     final PreparedStatement ret = con.prepareStatement(SQL_UPDATE); 
     ret.setArray(1, con.createArrayOf(ARRAY_DATATYPE, existing)); 
     ret.setDate(2, new java.sql.Date(dt.getMillis())); 
     return ret; 
    } 
}); 
+0

Работает только с простым JdbcTemplate, для NamedParameterJdbcTemplate, пожалуйста, проголосуйте https://jira.spring.io/browse/SPR-13178 –

-1
java.sql.Array intArray = connection.createArrayOf("int", existing); 
List<Object> values= new ArrayList<Object>(); 
values.add(intArray); 
values.add(dt); 
getJdbcTemplate().update(SQL_UPDATE,values); 
+0

Не могли бы вы отредактировать его с краткими объяснениями, пожалуйста? –

+0

Он «вдохновлен» на 4 года старше ответа. Вы просто пытаетесь скопировать его, сделав немного mish-mash, что делает его намного хуже (например, вам нужно теперь обрабатывать SQLException, что даже не показано в вашем «коде»). –

1

Это решение своего рода обходной путь с использованием PostGreSQL встроенной функции, которая определенно работает для меня.

reference blog

1) Преобразование массива строк, разделенных запятыми

Если вы используете Java8, это довольно легко. другие варианты here

String commaSeparatedString = String.join(",",stringArray); // Java8 feature 

2) PostgreSQL встроенная функция string_to_array()

вы можете найти другие функции массива PostGreSQL here

// tableName (name text, string_array_column_name text[]) 

String query = "insert into tableName(name,string_array_column_name) values(?, string_to_array(?,','))"; 


int[] types = new int[] { Types.VARCHAR, Types.VARCHAR}; 

Object[] psParams = new Object[] {"Dhruvil Thaker",commaSeparatedString }; 

jdbcTemplate.batchUpdate(query, psParams ,types); // assuming you have jdbctemplate instance 
+0

Ваше решение основано на asscumption, что запятые не являются законными в строке ввода, OP не указал такое предположение. Почему сообщение плохое решение через 5 лет после того, как хороший был опубликован? –