【问题标题】:PostgreSQL equivalent to SQL Server's TVPPostgreSQL 相当于 SQL Server TVP
【发布时间】:2020-11-06 22:22:07
【问题描述】:

SQL Server 具有表值参数,允许您将值数组作为参数传递。

实现类似于 PostgreSQL 查询的适当方法是什么,以便我可以执行以下操作:

select * from product where id in ($1)

我正在使用 Npgsql .NET 库。

https://www.nuget.org/packages/Npgsql/3.0.5

【问题讨论】:

  • 也许更详细的解释会有所帮助;在您的示例中,$1 来自哪里?能否提供一个完整的 MS SQL 示例?
  • 好点@IMSoP,我已将该信息添加到问题中。使用 .NET 库。
  • 在 PostgreSQL 中,您可以使用数组而不是 ID 列表:... where id = any($1 ::int[]) 其中 $1 是一个字符串参数,看起来像 {1, 2, 3} 不确定 C# 是否直接支持数组参数。
  • @Abelisto 哦!我现在就去试试!
  • @Abelisto 效果很好!请将其添加为答案,以便我接受。

标签: .net postgresql npgsql


【解决方案1】:

在 PostgreSQL 中,您可以使用数组而不是 ID 列表,例如:

... where id = any('{1, 2, 3}'::int[])

... where id = any(array[1, 2, 3])

这意味着id 是数组的一项。

Read more about arrays operators and functions.

要将数组作为参数从第三方语言传递,您至少可以使用第一个变体:

... where id = any($1 ::int[])

其中 $1 是一个字符串参数,类似于 {1, 2, 3}。请注意 $1::int[] 之间的空格 - 对于某些客户端来说可能是必需的。

不确定 C# 是否直接支持数组参数。

【讨论】:

  • 请注意,Npgsql 支持数组类型,因此您绝对可以从 C# 执行上述操作
【解决方案2】:

在 Postgres 中,您可以通过两种方式使用 IN 运算符:

expression IN (value [, ...])
expression IN (subquery)

阅读文档: first variantsecond variantthis overview

【讨论】:

  • 我试图找出它是否可以作为参数传递。使用使用 TVP 的 SQL Server,您可以执行 where id in (select id from @ListOfIds),否则在 PostgreSQL 中我必须每次使用 Id 列表生成查询。
【解决方案3】:

这是一个使用 Dapper 和 Npgsql 在 C# 中插入的示例 - 它将 1、2、3 插入到临时表中,然后按降序选择它们,因此它将打印 3 2 1 到控制台。这里的技巧是 Postgres unnest() 函数,它将数组扩展为一组行:

var results = await conn.QueryAsync<int>(@"
    CREATE TEMPORARY TABLE DapperNpgsqlArrayParameterDemo (id int not null primary key);
    INSERT INTO DapperNpgsqlArrayParameterDemo (id) SELECT unnest(@numbers);
    SELECT id from DapperNpgsqlArrayParameterDemo order by id desc;",
    new { numbers = new int[] { 1, 2, 3 } });
foreach(var item in results)
{
    Console.WriteLine($"found {item}.");
}

【讨论】:

    猜你喜欢
    • 2013-04-27
    • 1970-01-01
    • 2021-05-05
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2011-03-27
    • 2018-10-21
    相关资源
    最近更新 更多