如何根据多个条件更新多行?

时间:2019-10-21 15:01:53

标签: spring postgresql spring-batch

我正在尝试为许多行更新表中的单个列,但是每行将基于其他两列的唯一where条件而具有不同的更新日期值。我正在从csv中读取数据,并仅通过其他两列中的值组合来更新行中的日期列。

我已经看到了

SQL update multiple rows based on multiple where conditions

,但SET值将不是静态的,并且需要与其他两列值为true的每一行匹配。这是因为在我的表中,其他两个列的组合始终是唯一的。

伪代码

UPDATE mytable SET date = (many different date values)
WHERE col_1 = x and col_2 = y

col_1和col_2的值对于csv中的每一行都会更改,因为这两个值的组合是唯一的。我一直在考虑在postgres中使用CASE,但我知道它不能与多列一起使用。

因此,基本上,一个csv行具有一个日期值,该值必须在col_1和col_2等于其在csv行中各自值的记录中进行更新。如果数据库中不存在这些值,则将其忽略。

是否有一种优雅的方法可以在单个查询中执行此操作?该查询是spring批处理作业的一部分,因此我可能无法使用本机的postgres语法,但是我甚至在努力理解查询的格式,因此稍后可能会担心语法。我需要多个更新语句吗?如果是这样,我如何在春季批处理作业的写入步骤中实现这一目标?

编辑:添加一些示例数据以说明过程

CSV行:

date,        col_1,    col_2
2021-12-30,  'abc',    'def'
2021-05-30,  'abc',    'zzz'
2021-07-30,  'hfg',    'xxx'

我将需要查询来查找col_1 ='abc'AND col_2 = def的记录,然后将日期列更改为2021-12-30。我需要为每一行执行此操作,但是我不知道如何格式化UPDATE查询。

2 个答案:

答案 0 :(得分:1)

您可以将CSV数据插入(临时)表(例如mycsv)中,并将UPDATEFROM子句一起使用。例如:

CREATE TEMP TABLE mycsv (date DATE, col_1 TEXT, col_2 TEXT);
COPY mycsv FROM '/path/to/csv/csv-file.csv' WITH (FORMAT csv);
UPDATE mytable m SET date = c.date 
FROM mycsv c WHERE m.col_1 = c.col_1 AND m.col_2 = c.col_2;

答案 1 :(得分:1)

创建一个Itemwriter实现,并覆盖write()方法。该方法接受一个对象列表,每个对象都是从ItemProcessor实现返回的。

在write方法中,只需遍历对象,然后依次对每个对象调用update。

例如:

在ItemWriter中:

 @Autowired
 private SomeDao dataAccessObject;

 @Override
 public void write(List<? extends YourDTO> someDTOs) throws Exception {

   for(YourDTO dto: someDTOs) {
      dataAccessObject.update(dto);
   }
 }

在您的DAO中:

private static final String sql = "UPDATE mytable SET dateField = ? WHERE col_1 = ? and col_2 = ?";

public void update(YourDTO dto) {

   Object[] parameters = { dto.getDate(), dto.getCol1(), dto.getCol2()};
   int[] types = {Types.DATE, Types.STRING, Types.STRING}; 

   jdbcTemplate.update(sql, parameters, types); 
}