JDBC PreparedStatement в пакете, когда устанавливаемые столбцы варьируются от строки к строке - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь выполнять пакетное обновление, используя PreparedStatement, где данные, которые вы получаете, зависят от того, что у вас есть.

Простой пример:

У вас есть таблица со столбцами x и y. Ваши входные данные - это представление строк, в которых присутствует только измененный столбец. Таким образом, для строки 1 у вас есть x = 'foo', а для строки 2 у вас есть y = 'bar'. Чтобы связать их с PreparedStatement, вам нужен один оператор SQL: «обновить таблицу, где x = ?, y =? Где и т. Д.».

Решением, над которым я работаю, является установка столбца, в котором у вас нет значения, уже существующего, но я не уверен, возможно ли это. В сыром SQL вы могли бы написать «обновить таблицу, где x = x и y = 'foo', где и т. Д.», Однако я не нашел никаких способов добиться этого, установив «?»Параметр, являющийся ссылкой на столбец, кажется невозможным.

Можно ли вообще разобраться с этим делом с помощью PreparedStatements? Я прошу прощения, если мое объяснение плохое.

Ответы [ 2 ]

2 голосов
/ 02 октября 2019

Предполагая, что все значения, которые вы хотите установить, не равны NULL, вы можете использовать оператор типа

update sometable set column1 = coalesce(?, column1), colum2 = coalesce(?, column2)

Тогда, когда значение не нужно обновлять, используйте либо PreparedStatement.setNull с соответствующим java.sql.Types значение или PreparedStatement.setXXX соответствующего типа с null в качестве значения.

Как обсуждалось в комментариях, альтернативой, если вам нужно обновить до null, является использование пользовательской функциисо значением Sentinel (либо для обновления до нуля, либо для использования текущего значения). Что-то вроде:

update sometable set column1 = conditional_update(?, column1), colum2 = conditional_update(?, column2)

Где conditional_update будет что-то вроде (с использованием синтаксиса Firebird 3 PSQL):

create function conditional_update(new_value varchar(500), original_value varchar(500)) 
  returns varchar(500)
as
begin
  if (new_value = '$$NO_UPDATE$$') then
     return original_value;
  else
     return new_value;
end

Где использование $$NO_UPDATE$$ - это значение стража для отсутствия обновления. Потенциальным недостатком этого решения является ввод столбцов в виде строкового типа. Вам всегда нужно использовать строковые типы (я не уверен, существуют ли базы данных, которые бы поддерживали динамические параметры и возвращаемые типы в этой ситуации).

1 голос
/ 02 октября 2019

Позвольте мне перефразировать вашу проблему, и вы, пожалуйста, скажите мне, если это правильно: вы хотите иметь возможность обновления

  • иногда вы обновляете только для определенного x
  • иногда вы обновляете только для определенного y
  • иногда вы обновляете для конкретного x и y вместе

Правильно? Если «да», то следующая проблема - это возможности реализации.

Вы предложили попытаться поместить сам столбец в параметр. Даже если это возможно, я все равно рекомендую против этого. Код запутается.

Я предлагаю вам создать java-метод, который создает и возвращает строку запроса (или, по крайней мере, предложение 'where') на основе доступных параметров (x, y и т. Д.). Ваш коддля вызова оператора JDBC Prepared вызовет этот метод для получения строки запроса. Вы все равно выиграете от использования подготовленных заявлений. Стоимость состоит в том, что ваша база данных будет кэшировать несколько разных операторов вместо одного, но я думаю, что это минимальная проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...