web-dev-qa-db-ja.com

パラメーターとしてのPostgres整数配列?

Postgres pureでは、整数配列を関数に渡すことができますが、これは.NETデータプロバイダーNpgsqlではサポートされていないことを理解しています。

現在、ストアドプロシージャへの呼び出しを読み込み、パラメーターを追加し、スカラーを実行してIdを取得してオブジェクトに入力するDbCommandがあります。

これは、引数としてn個の整数を取る必要があります。これらは、idによって新しく作成されたレコードを整数引数にリンクする子レコードを作成するために使用されます。

理想的には、各整数に対してDbCommandで複数のExecuteNonQuery呼び出しを行う必要はないため、データベース側で分割されるパラメーターとしてcsv文字列を作成しようとしています。

私は通常、Dbの抽象化を味わうLINQ 2 SQLに住んでいますが、手動データアクセスを使用してこのプロジェクトに取り組んでいますが、少し汚くなっています。

31

参照: 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])
    
50
vladr

これは古い質問であることに気づきましたが、良い解決策を見つけるのに数時間かかり、私が学んだことを伝えたいと思いました ここ 、他の誰かをトラブルから救います。たとえば、試してみてください

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;

commandはNpgsqlCommandです(Visual StudioでC#とNpgsqlを使用)。

47
brichins

always適切にフォーマットされた文字列を使用できます。秘trickはフォーマットです。

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"}')のようになり、これは機能します。

1
user2738265