Целочисленные массивы Postgres в качестве параметров?
Я понимаю, что в Postgres pure вы можете передать целочисленный массив в функцию, но это не поддерживается в провайдере данных .NET Npgsql.
в настоящее время у меня есть DbCommand, в который я загружаю вызов хранимой proc, добавляю параметр и выполняю скаляр, чтобы вернуть идентификатор для заполнения объекта.
теперь в качестве аргументов нужно взять n целых чисел. Они используются для создания дочерних записей, связывающих вновь созданную запись по ее идентификатору с целым числом аргументы.
В идеале я бы предпочел не делать несколько вызовов ExecuteNonQuery на моей DbCommand для каждого из целых чисел, поэтому я собираюсь построить строку csv в качестве параметра, который будет разделен на стороне базы данных.
Я обычно живу в LINQ 2 SQL, наслаждаясь абстракцией БД, работая над этим проектом с ручным доступом к данным, все это просто становится немного грязным, как люди обычно передают эти параметры в postgres?
3 ответов
см.: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(,','); ... 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])
Я понимаю, что это старый вопрос, но мне потребовалось несколько часов, чтобы найти хорошее решение и подумал, что я передам то, что узнал здесь и избавить кого-то еще от неприятностей. Попробуйте, например,
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 (с использованием C# и Npgsql в Visual Studio).
вы можете всегда используйте правильно отформатированную строку. Фокус в форматировании.
command.Parameters.Add("@array_parameter", string.Format("{{{0}}}", string.Join(",", array));
обратите внимание, что если Ваш массив представляет собой массив строк, вам нужно будет использовать array.Выберите (value => string.Формат("\"{0}\", value)) или эквивалент. Я использую этот стиль для массива перечисляемого типа в PostgreSQL, потому что нет автоматического преобразования из массива.
в моем случае мой перечисляемый тип имеет некоторые значения, такие как'value1', 'value2', 'value3', и мое перечисление C# имеет совпадающие значения. В моем случае окончательный SQL-запрос выглядит примерно так (e ' {"value1", "value2"}'), и это работает.