Постгрессирует целочисленные массивы в качестве параметров?
Я понимаю, что в Postgres pure вы можете передать целочисленный массив в функцию, но это не поддерживается в поставщике данных .NET Npgsql.
В настоящее время у меня есть DbCommand, в который я загружаю вызов хранимой процедуры, добавляю параметр и выполняю скаляр, чтобы вернуть идентификатор для заполнения объекта.
Теперь нужно принять n целых чисел в качестве аргументов. Они используются для создания дочерних записей, связывающих вновь созданную запись с идентификатором id с целыми аргументами.
В идеале мне бы не пришлось делать несколько вызовов ExecuteNonQuery для моего DbCommand для каждого из целых чисел, поэтому я собираюсь построить строку csv в качестве параметра, который будет разделен на стороне базы данных.
Я обычно живу в LINQ 2 SQL, наслаждаясь абстракцией Db, работая над этим проектом с ручным доступом к данным, все это просто становится немного грязным, как люди обычно идут о передаче этих параметров в postgres?
Ответы
Ответ 1
Смотрите: http://www.postgresql.org/docs/9.1/static/arrays.html
Если ваш не-родной драйвер по-прежнему не позволяет передавать массивы, вы можете:
-
передать строковое представление массива (который ваша хранимая процедура может затем анализировать в массив - см. string_to_array
)
CREATE FUNCTION my_method(TEXT) RETURNS VOID AS $$
DECLARE
ids INT[];
BEGIN
ids = string_to_array($1,',');
...
END $$ LANGUAGE plpgsql;
затем
SELECT my_method(:1)
с: 1 = '1,2,3,4'
-
полагается на сам Postgres для перевода из строки в массив
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$
...
END $$ LANGUAGE plpgsql;
затем
SELECT my_method('{1,2,3,4}')
-
выберите не использовать переменные связывания и выдайте явную командную строку со всеми указанными параметрами (убедитесь, что проверяете или удаляете все параметры, исходящие извне, чтобы избежать атак SQL-инъекций.)
CREATE FUNCTION my_method(INT[]) RETURNS VOID AS $$
...
END $$ LANGUAGE plpgsql;
затем
SELECT my_method(ARRAY [1,2,3,4])
Ответ 2
Я понимаю, что это старый вопрос, но мне потребовалось несколько часов, чтобы найти хорошее решение и подумал, что я передам то, что я узнал здесь и спасти кого-то еще от неприятностей. Попробуйте, например,
SELECT * FROM some_table WHERE id_column = ANY(@id_list)
где @id_list привязан к параметру int [] с помощью
command.Parameters.Add("@id_list", NpgsqlDbType.Array | NpgsqlDbType.Integer).Value = my_id_list;
где команда NpgsqlCommand (с использованием С# и Npgsql в Visual Studio).
Ответ 3
Вы всегда можете использовать правильно отформатированную строку. Трюк - это форматирование.
command.Parameters.Add("@array_parameter", string.Format("{{{0}}}", string.Join(",", array));
Обратите внимание, что если ваш массив является массивом строк, вам нужно будет использовать array.Select(value = > string.Format( "\" {0}\", value)) или эквивалент. этот стиль для массива перечисляемого типа в PostgreSQL, потому что нет автоматического преобразования из массива.
В моем случае мой перечисляемый тип имеет некоторые значения, такие как 'value1', 'value2', 'value3', а мое перечисление С# имеет соответствующие значения. В моем случае конечный SQL-запрос заканчивается тем, что выглядит как (E '{ "value1", "value2" }'), и это работает.