Postgres整数数组作为参数?

时间:2009-02-20 17:03:18

标签: arrays postgresql argument-passing

据我所知,在Postgres pure中,您可以将整数数组传递给函数,但.NET数据提供程序Npgsql不支持这种情况。

我目前有一个DbCommand,我在其中加载对存储过程的调用,添加一个参数并执行标量以获取用于填充对象的Id。

现在需要将n个整数作为参数。这些用于创建子记录,将新创建的记录通过它的id链接到整数参数。

理想情况下,我不必为每个整数在DbCommand上进行多次ExecuteNonQuery调用,因此我将构建一个csv字符串作为将在数据库端拆分的参数。

我通常生活在使用Db抽象的LINQ 2 SQL中,使用手动数据访问来处理这个项目它只是变得有点脏,人们通常如何将这些参数传递给postgres?

4 个答案:

答案 0 :(得分:48)

请参阅: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)
    

    with: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])
    

答案 1 :(得分:47)

我意识到这是一个古老的问题,但我花了几个小时才找到一个好的解决方案,并认为我会传递我学到的东西here并为别人解决问题。例如,尝试

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

答案 2 :(得分:1)

您可以始终使用格式正确的字符串。诀窍是格式化。

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”}'),这是有效的。

答案 3 :(得分:0)

<块引用>

完整的编码结构

postgresql 函数

CREATE OR REPLACE FUNCTION admin.usp_itemdisplayid_byitemhead_select(
    item_head_list int[])
    RETURNS TABLE(item_display_id integer) 
    LANGUAGE 'sql'

    COST 100
    VOLATILE 
    ROWS 1000
    
AS $BODY$ 
        SELECT vii.item_display_id from admin.view_item_information as vii
where vii.item_head_id = ANY(item_head_list);
    $BODY$;

模型

public class CampaignCreator
    {
        public int item_display_id { get; set; }
        public List<int> pitem_head_id { get; set; }
    }

.NET CORE 功能

DynamicParameters _parameter = new DynamicParameters();
                _parameter.Add("@item_head_list",obj.pitem_head_id);
                
                string sql = "select * from admin.usp_itemdisplayid_byitemhead_select(@item_head_list)";
                response.data = await _connection.QueryAsync<CampaignCreator>(sql, _parameter);