2009-02-20 75 views
20

我明白,在Postgres pure中,您可以将整数数组传递到函数中,但.NET数据提供程序Npgsql不支持此功能。Postgres整型数组作为参数?

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

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

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

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

+3

对于那些w ho不要读过选定的答案:数组参数*受.NET Npgsql提供程序支持(尽管我不能说在提问时这是否为真)。看到我的[下面的答案](http://stackoverflow.com/a/7733714/957950)。 – brichins 2014-09-30 13:40:59

回答

36

参见: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]) 
    
+0

谢谢!不,我没有,我依靠我的同事告诉我的。我会给它一个镜头。 – 2009-02-20 23:15:50

+1

您是否有任何证据证明PG中没有准备好的语句的本地支持?在[手册](http://www.postgresql.org/docs/9.2/static/sql-prepare.html)中找不到任何提及的事实。至于日志记录,我猜服务器在执行时记录查询,因为它们是从客户端传递过来的,因此日志中没有“EXECUTE”语句。 – 2012-08-13 14:33:54

+1

@IhorKaharharhenko的措辞很差,而且是无关紧要的。编辑回复。回覆。原始声明中,驱动程序不会使用`PREPARE`,除非启用了服务器端预处理语句(有时是显式的),并且在某些情况下,除非某个命令超出了某个执行次数阈值。如果在`postgresql.conf`中启用了命令日志记录,那么你会看到实际的`SELECT` /`INSERT`/etc。当不使用服务器端预处理语句时的命令。 – vladr 2012-08-13 18:11:57

35

我意识到这是一个老问题,但我花了几个小时找到一个很好的解决方案,以为我” d传递我所学到的here并拯救别人的麻烦。尝试,例如,

SELECT * FROM some_table WHERE id_column = ANY(@id_list) 

其中@id_list是由

command.Parameters.Add("@id_list", NpgsqlDbType.Array | NpgsqlDbType.Integer).Value = my_id_list; 

方式结合到一个int []参数,其中命令是NpgsqlCommand(使用C#和Npgsql的在Visual Studio)。

2

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

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

需要注意的是,如果你的阵列是一个字符串数组,那么你就需要使用array.Select(值=>的String.Format( “\”{0} \”,值))或者相当于我在PostgreSQL中使用这种样式的枚举类型,因为没有自动从数组中转换。

在我的例子中,我的枚举类型有一些值,如'value1','value2', 'value3',而我的C#枚举具有匹配的值。在我的情况下,最终的SQL查询最终看起来像(E'{“value1”,“value2”}'),并且这个工作。