Целочисленные массивы Postgres в качестве параметров? - PullRequest
30 голосов
/ 20 февраля 2009

Я понимаю, что в чистом Postgres вы можете передать целочисленный массив в функцию, но это не поддерживается в провайдере данных .NET Npgsql.

В настоящее время у меня есть DbCommand, в который я загружаю вызов сохраненного процесса, добавляю параметр и выполняю скаляр, чтобы получить Id для заполнения объекта.

Теперь нужно принять n целых чисел в качестве аргументов. Они используются для создания дочерних записей, связывающих вновь созданную запись по ее идентификатору с целочисленными аргументами.

В идеале я бы предпочел не делать несколько вызовов ExecuteNonQuery для моей DbCommand для каждого из целых чисел, поэтому я собираюсь создать строку csv в качестве параметра, который будет разделен на стороне базы данных.

Обычно я живу в LINQ 2 SQL, наслаждаясь абстракцией Db, работая над этим проектом с ручным доступом к данным, все становится немного грязным, как люди обычно передают такие параметры в postgres?

Ответы [ 3 ]

48 голосов
/ 20 февраля 2009

См .: 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])
    
47 голосов
/ 12 октября 2011

Я понимаю, что это старый вопрос, но мне потребовалось несколько часов, чтобы найти хорошее решение, и подумал, что передам то, что узнал здесь , и избавлю кого-то еще от неприятностей. Попробуйте, например,

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).

1 голос
/ 02 сентября 2013

Вы можете всегда использовать правильно отформатированную строку. Хитрость в форматировании.

command.Parameters.Add("@array_parameter", string.Format("{{{0}}}", string.Join(",", array));

Обратите внимание, что если ваш массив представляет собой массив строк, вам нужно будет использовать array.Select (value => string.Format ("\" {0} \ ", value)) или эквивалентный. Я использую этот стиль для массива перечислимого типа в PostgreSQL, потому что нет автоматического преобразования из массива.

В моем случае мой перечисляемый тип имеет некоторые значения, такие как 'value1', 'value2', 'value3', а мое перечисление C # имеет совпадающие значения. В моем случае окончательный SQL-запрос выглядит примерно так (E '{"value1", "value2"}'), и это работает.

...