Как передать кортежи (не массивы) в качестве параметров ограничения WHERE в запросе SQL через клиентскую библиотеку (Postgres)?

Я эмпирически обнаружил, что PostgreSQL позволяет вам создавать "кортежи" (моя терминология, я не знаю, как они это называют) для определения условия с несколькими столбцами в WHERE:

update T set x=true where (a_id, b_id) IN ((3428, 3544), (3450, 3542));

Это, кажется, делает именно то, что я надеюсь, что будет делать: x обновляется, где a_id = первый элемент в кортеже И b_id = второй элемент в кортеже. Это близко к тому, чтобы быть полезным, но для того, чтобы это действительно имело значение, я должен иметь возможность установить эти "кортежи" в качестве параметров из клиентской библиотеки; особенно, node-pg в этом случае.

Можно ли привязать $1 к чему-либо в следующем запросе, так что $1 - это список из 0 или более пар a_id а также b_id?

client.query("UPDATE t SET x=true WHERE (a_id, b_id) IN $1"), [...?])

Если нет, могу ли я хотя бы сделать

client.query("UPDATE t SET x=true WHERE (a_id, b_id) IN ($1, $2, ...$N)", [ a1b1, a1b2, ...aNbN ])

?

1 ответ

Ниже представлен способ передачи массива целых чисел с одним аргументом в неназванный подготовленный оператор, но я уверен, что это можно использовать, но, безусловно, выполнимо с помощью node-postgres.

SQL:

f=# create table nu(i int, t text);
CREATE TABLE
f=# insert into nu values (1,'a'),(2,'a'),(4,'a');
INSERT 0 3
f=# select * from nu;
 i | t
---+---
 1 | a
 2 | a
 4 | a
(3 rows)

ЯШ:

client.query("update nu set t = 'b' where i = any ($1::int[]) returning *", [[1,2,3]], (err, res) => {
  console.log(err, res.rows)
  client.end()
})

выход:

null [ anonymous { i: 1, t: 'b' }, anonymous { i: 2, t: 'b' } ]

дополнительная проверка:

f=# select * from nu;
 i | t
---+---
 4 | a
 1 | b
 2 | b
(3 rows)

Что касается второго способа - это сделано именно так, как вы показываете в своем примере

ОБНОВИТЬ

Из-за моего неточного чтения я снова ответил на другой вопрос. все же я решил оставить выше, так что следующий фрагмент кода будет более понятным:

client.query("update nu set t = 'foo' where (i,t)::text = any ($1::text[]) returning *", ['{"(1,b)","(2,b)"}'], (err, res) => {
  console.log(err, res.row)
  client.end()
})

и таким образом заявление произвело:

t 2017-10-26 07:53:25 UTC :: LOG:  execute <unnamed>: update nu set t = 'foo' where (i,t)::text = any ($1::text[]) returning *
t 2017-10-26 07:53:25 UTC :: DETAIL:  parameters: $1 = '{"(1,b)","(2,b)"}'

и результат:

f=# select * from nu;
 i |  t
---+-----
 4 | a
 1 | foo
 2 | foo
(3 rows)
Другие вопросы по тегам