Массовое обновление нескольких строк в одном запросе с использованием PostgreSQL - PullRequest
1 голос
/ 14 июля 2020

Я хочу обновить несколько строк в PostgreSQL и Go в одном операторе. Есть ли способ сделать что-то вроде следующего?

UPDATE table 
SET column_a = "FINISH", 
    column_b = 1234 
WHERE id = '1',
    column_a = "UNFINISH", 
    column_b = 3124 
WHERE id = '2' 

и есть ли пример, если выполняется на go языке?

Ответы [ 4 ]

0 голосов
/ 14 июля 2020

Мне нравится структурировать это с помощью производной таблицы:

UPDATE t
    SET column_a = v.column_a,
        column_b = v.column_b
    FROM (VALUES (1, 'FINISH', 1234),
                 (2, 'UNFINISH', 3124)
         ) v(id, column_a, column_b)
    WHERE v.id = t.id;

Это упрощает добавление дополнительных значений - как id s, так и столбцов - без усложнения запроса. Кроме того, он менее подвержен случайным ошибкам.

0 голосов
/ 14 июля 2020

В postgresql вы можете использовать подход обновления из значений, описанный в ответах здесь: Обновить несколько строк в одном запросе, используя PostgreSQL

И в Go вы можете реализовать это так:

func updateWithSlice(slice []T) error {
    var queryString = `UPDATE "table" AS t SET (
        "column_a"
        , "column_b"
    ) = (
        x."column_a"::text
        , x."column_b"::integer
    )
    FROM (VALUES` // `

    numColumns := 3 // the number of columns you want to update + 1 for the id column
    params := make([]interface{}, len(slice)*numColumns)
    for i, t := range slice {
        pos := i * numColumns

        params[pos+0] = t.ColumnA
        params[pos+1] = t.ColumnB
        params[pos+2] = t.Id

        queryString += `($` + strconv.Itoa(pos+1) +
            `,$` + strconv.Itoa(pos+2) +
            `,$` + strconv.Itoa(pos+3) +
            `),`
    }

    queryString = queryString[:len(queryString)-1] // drop last ","
    queryString += ` ) AS x (
        "column_a"
        , "column_b"
        , "id"
    )
    WHERE t."id" = x."id"::integer` // `

    _, err := db.Exec(queryString, params...)
    return err
}
0 голосов
/ 14 июля 2020

Я думаю, вы хотите:

update mytable
set 
    column_a = case when id = 1 then 'FINISH' else 'UNFINISHED' end,
    column_b = case when id = 1 then 1234     else 3124 end
where id in (1, 2)

Обоснование:

  • предложение where фильтрует только id s, которые вы хотите update , что более эффективно (при условии, что у вас есть индекс на id) и упрощает условный лог. c

  • id выглядит как число, поэтому его следует рассматривать как таковой (ie, не заключайте буквальные значения в кавычки)

  • буквальные строки должны быть заключены в одинарные кавычки - двойные кавычки означают идентификаторы (например, имена столбцов)

0 голосов
/ 14 июля 2020

Вы можете использовать выражение CASE.

UPDATE table 
SET 
  column_a = CASE WHEN id = '1' THEN 'FINISH'
                  WHEN id = '2' THEN 'UNFINISH'
                  ELSE 'SOMETHING'
             END,
  column_b = CASE WHEN id = '1' THEN 1234
                  WHEN id = '2' THEN 3124
                  ELSE 0
             END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...