Передать массив из node-postgres в функцию plpgsql

Функция plpgsql:

CREATE OR REPLACE FUNCTION testarray (int[]) returns int as $$
  DECLARE
    len int;
  BEGIN
    len := array_upper($1);
  return len;
  END
$$ language plpgsql;

Запрос node-postgres + тестовый массив:

var ta = [1,2,3,4,5];
client.query('SELECT testarray($1)', [ta], function(err, result) {
  console.log('err: ' + err);
  console.log('result: ' + result);
});

Вывод с сервера узла:

ошибка: ошибка: значение массива должно начинаться с "{" или информации о размерах
результат: не определено

Я также попытался привести параметр в запросе клиента, как testarray($1::int[]) который вернул ту же ошибку.

Я изменил аргумент функции на (anyarray int) и ошибка вывода изменилась:

ошибка: ошибка: неверный синтаксис ввода для целого числа: "1,2,3,4,5"
результат: не определено

А также пара других вариаций.

Я ищу вариант, который не дает ошибки и возвращает 5.

Я читал о проблеме с массивом разбора Postgres и вопросом о стеке потока для параметризованных массивов в node-postgres:

Но ответа, похоже, там не было.

3 ответа

Параметр должен быть в одной из следующих форм:

'{1,2,3,4,5}'         -- array literal
'{1,2,3,4,5}'::int[]  -- array literal with explicit cast
ARRAY[1,2,3,4,5]      -- array constructor

Также вы можете упростить вашу функцию:

CREATE OR REPLACE FUNCTION testarray (int[])
  RETURNS int AS
$func$
BEGIN
  RETURN array_length($1, 1);
END
$func$ LANGUAGE plpgsql IMMUTABLE;

Или простая функция SQL:

CREATE OR REPLACE FUNCTION testarray2 (int[])
  RETURNS int AS 'SELECT array_length($1, 1)' LANGUAGE sql IMMUTABLE;

Или просто использовать array_length($1, 1) непосредственно.

Благодаря ответам от PinnyM и Эрвина. Я просмотрел варианты и перечитал соответствующие ответы.

форматы массивов, описанные Эрвином, работают в node-postgres буквально следующим образом:

'select testarray(' + "'{1,2,3,4,5}'" + ')'
'select testarray(' + "'{1,2,3,4,5}'" + '::INT[])'
'select testarray(ARRAY[1,2,3,4,5])'

TL: Dr цитирования JavaScript

параметризировать их в node-postgres: (основываясь на этом ответе)

var ta = [1,2,3,4,5];
var tas = '{' + ta.join() + '}';

...skipped over the pg connect code

client.query("select testarray($1)", [tas] ...
client.query("select testarray($1::int[])", [tas] ...
not sure about the ARRAY constructor.

Основываясь на ответе, который вы разместили, это может работать для вас:

var ta = [1,2,3,4,5];
var params = [];
for(var i = 1, i <= ta.length; i++) {
    params.push('$'+i);
}
var ta = [1,2,3,4,5];
client.query('SELECT testarray(\'{' + params.join(', ') + '}\')', ta, function(err, result) {
  console.log('err: ' + err);
  console.log('result: ' + result);
});
Другие вопросы по тегам