Передать массив целых чисел в массиве параметров

Я пытаюсь передать массив параметров в массив параметров pg-promise, как рекомендовано в документы pg-promise.

db.any("SELECT fieldname FROM table WHERE fieldname = $1 AND fieldname2 IN ($2)",
        [1,[[1730442],[1695256]],[487413],[454336]]])
    .then(function (data) {
        console.log("DATA:", data); // print data;
    })
    .catch(); 

Но это не работает, мне возвращается ошибка «отсутствует) после списка аргументов». Или ошибка «оператор не существует: целое = целое []]», если я заменю параметры на:

[1,[1730442]]

Конечно, если я передам это так, это сработает:

[1,1730442]

Это правильный способ передачи массива значений, когда задействованы другие параметры?

Я также пытался удалить скобки вокруг 2 долларов, но безуспешно.


person Standaa - Remember Monica    schedule 25.04.2016    source источник
comment
В вашем примере вы не передаете массив целых чисел в качестве параметра, это массив массивов целых чисел. Какой из них вы на самом деле хотите?   -  person vitaly-t    schedule 25.04.2016


Ответы (2)


Я автор pg-promise.


В вашем примере какая-то путаница...

Вы используете только две переменные в запросе, но передаете четыре значения:

  • 1
  • [[1730442],[1695256]]
  • [487413]
  • [454336]

И ваш синтаксис не является допустимым JavaScript, так как вы используете ] в конце без соответствующего открывающего, поэтому трудно понять, что именно вы пытаетесь передать.

И тогда зачем снова заворачивать все значения в массивы? Я считаю, что это просто список целых чисел, которые вы хотите внутри оператора IN().

Когда вы хотите использовать значения в пределах WHERE IN(), это не массив тех значений, которые вы хотите передать, это список значений, разделенных запятыми.

Если вы измените свой пример на следующий:

db.any('SELECT fieldname FROM table WHERE fieldname = $1 AND fieldname2 IN ($2:csv)',
[1, [1730442,1695256,487413,454336]])

Вы получите правильный список введенных значений.

Смотрите также:

person vitaly-t    schedule 25.04.2016
comment
Спасибо за исчерпывающий ответ. Третий ] только потому, что я передавал как целое число, так и массив целых чисел. Однако я не заметил обозначения ($ 2: csv) в документах. - person Standaa - Remember Monica; 26.04.2016
comment
comment
Только что проверил, работает. Еще раз спасибо за вашу помощь и за эту замечательную библиотеку. - person Standaa - Remember Monica; 26.04.2016

Другая возможность:

db.any("SELECT fieldname FROM table WHERE fieldname = $1 AND fieldname2 = any ($2)",
        [1,[1730442,1695256,487413,454336]])
    .then(function (data) {
        console.log("DATA:", data); // print data;
    })
    .catch(); 

Из руководства по postgresql здесь: https://www.postgresql.org/docs/9.5/static/functions-comparisons.html

Правая часть представляет собой выражение в скобках, которое должно возвращать значение массива. Левое выражение оценивается и сравнивается с каждым элементом массива с использованием заданного оператора, который должен давать логический результат. Результат ANY является "истинным", если получен любой истинный результат. Результат "false", если истинный результат не найден (включая случай, когда массив имеет нулевые элементы).

Если выражение массива дает нулевой массив, результатом ANY будет нуль. Если левое выражение дает null, результат ANY обычно равен null (хотя оператор нестрогого сравнения может дать другой результат). Кроме того, если правый массив содержит нулевые элементы и не получен истинный результат сравнения, результатом ANY будет нуль, а не ложь (опять же, при условии строгого оператора сравнения). Это соответствует обычным правилам SQL для логических комбинаций нулевых значений.

НЕКОТОРЫЙ является синонимом ЛЮБОГО.

person Anatoly    schedule 03.11.2016
comment
Я чувствую, что вы только что повысили уровень моих навыков SQL. Мне любопытно, есть ли у вас опыт работы с ошибками производительности с помощью этого метода? Как вы думаете, это в целом более производительно — потому что может стать подготовленным оператором — или просто наравне с формой IN? Другой? - person ggranum; 08.10.2017
comment
Ответил на мой собственный вопрос - он такой же, как и в 8.2: In existing releases, the form with IN (list-of-scalar-constants) can be optimized into indexscan(s), but = ANY (array) isn't. 8.2 will treat them equivalently (in fact, it converts IN (...) to = ANY (ARRAY[...]) !). So depending on your time horizon, you might wish to stick with whichever is cleaner for your calling code. regards, tom lane From postgresql.org/message-id/5373.1158351561%40sss.pgh.pa.us - person ggranum; 08.10.2017