Передать массив из 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)
непосредственно.
array_upper()
это неправильная функция. Массивы могут иметь произвольные подписки.array_length()
делает то, что вы ищете. Связанный вопрос:И то и другое
array_length()
а такжеarray_upper()
требуется два параметра. Второй размер массива -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])'
параметризировать их в 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);
});