Как передать кортежи (не массивы) в качестве параметров ограничения 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)