当前位置: 首页 > 知识库问答 >
问题:

将List作为参数传递到postgres函数中

邢承弼
2023-03-14

我有如下spring数据存储库界面:

public interface MyEntityRepository extends 
        JpaRepository<MyEntity, Long> {

    @Query(nativeQuery = true, value = "select * from my_func(:myList)")
    Page<MyEntity> findBy(
            @NonNull @Param("myList") List<String> myList,
            @NonNull Pageable pageable);

}

Postgres的函数我定义如下(但如果我做错了,我可以更改):

CREATE OR REPLACE FUNCTION my_func(variadic myList text[])
RETURNS SETOF myEntityTable AS $$
... some logic
select * from myEntityTable t where t.foo in (myList);

调用此存储库方法时,出现以下错误:

ERROR: operator does not exist: character varying = text[]
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Where: PL/pgSQL function f_najdi_autorizaciu_na_spracovanie(text[]) line 28 at RETURN QUERY

你能告诉我在postgres函数中应该使用什么类型吗?谢谢你的建议。

编辑:我不能使用本机查询上述存储库方法并将其传递到IN子句中,因为我在DB函数中有更多的逻辑、变量等。。。它必须是DB函数。

共有3个答案

宁飞宇
2023-03-14

不确定这是否会增加很多价值,我只是希望它能有所帮助。

PostgreSQL函数期望从列表中作为输入的最终格式为以下模式,使用数组:

select my_func(array['item1','item2']::my_type[]);

请参阅数据库管理员的完整示例。SE.

就你而言:

select my_func(array['item1','item2']::text[]);

我在自己的测试中发现

select my_func(array['item1','item2']);

应该已经足够了。

然后,唯一的目标是从原始java类型中获取此格式。另一个问题回答了这个问题。这个答案只是为了说明这一切的目的。

呼延俊良
2023-03-14

恐怕我不知道如何使用Spring Data JPA来实现这一点,但是使用普通的JDBC,您必须简单地将bind变量转换为text[],并传递一个String[]类型而不是列表。例如:

try (PreparedStatement s = conn.prepareStatement("select * from my_func(?::text[])")) {
    s.setObject(1, myList.toArray(new String[0]));

    try (ResultSet rs = s.executeQuery()) {
        // ...
    }
}

这里的关键信息是,JDBC驱动程序需要的是数组,而不是列表。

方嘉志
2023-03-14

我在类似情况下使用了以下变通解决方案:

1) 创建了两个助手函数:

-- Convert a variable number of text arguments to text array
-- Used to convert Java collection to the text array
--
create or replace function list_to_array(variadic _list text[]) returns text[] language sql as $$
select _list;
$$;
-- Convert the bytea argument to null.
-- Used to convert Java null to PostgreSQL null
--
create or replace function list_to_array(_list bytea) returns text[] language sql as $$
select null::text[];
$$;

2) 在主功能中使用any而不是中的,例如:

create or replace function my_func(_params text[]) 
returns table (field1 text, field2 text) 
language sql as 
$$
select
  t.field1 as field1,
  t.field2 as field2,
from
  my_table t
where
  array_length(_params, 1) is null or t.foo = any(_params);
$$;

3)然后在存储库方法中使用它们,例如:

@NonNull
@Query(value = "select ... from my_func(list_to_array(?1))", nativeQuery = true)
List<MyProjection> getFromMyFunc(@Nullable Set<String> params, @NonNull Pageable page);

 类似资料:
  • 问题内容: 如何在不执行“父”函数或不使用函数的情况下将函数作为参数传递?(因为我已经读到它是不安全的。) 我有这个: 它可以工作,但是问题是在调用函数时触发,而不是在函数中使用时触发。 根据我所读的内容,我可以使用来解决它,但这不是最佳实践。如何在JavaScript中将函数作为参数传递? 问题答案: 您只需要删除括号: 然后,这将传递函数而不先执行它。 这是一个例子:

  • 问题内容: 我已经熟悉Android框架和Java,并希望创建一个通用的“ NetworkHelper”类,该类可以处理大多数联网代码,使我能够从中调用网页。 我遵循了来自developer.android.com的这篇文章来创建我的网络类:http : //developer.android.com/training/basics/network- ops/connecting.html 码:

  • 问题内容: 我正在读一本教科书,我想知道我们传递给函数的参数为​​什么既不是原始的也不是用户定义的类实例。 我知道它是这两个之一。但是似乎在这里它传递了用户定义的构造方法,例如Runnable()。看来他们想在以后运行线程,但是什么时候?我认为这是合法的,但是我在Java类中从未听说过这种事情。 问题答案: 实际上,这是传递实现Runnable接口的匿名内部类的实例。在Java教程中阅读有关它们的

  • 问题内容: 我想使用数组作为参数调用一个函数: 有路过的内容的一种更好的方式进入? 问题答案: const args = [‘p0’, ‘p1’, ‘p2’]; call_me.apply(this, args); 请参阅MDN文档。 如果环境支持ECMAScript6,则可以改用传播参数:

  • 问题内容: 在Java中,如何将一个函数作为另一个函数的参数传递? 问题答案: Java 8及以上 如果你的类或接口只有一个抽象方法(有时称为SAM type),则使用Java 8+ lambda表达式,例如: 然后可以在使用MyInterface的任何地方替换lambda表达式: 例如,你可以非常快速地创建一个新线程: 并使用方法引用语法使其更加清晰: 如果没有 lambda表达式,则最后两个示

  • 假设我们有python中的函数: 虽然我可能会将传递给A,但我正在寻找一种优雅的方法来传递类似于的东西来执行。 我现在看到的唯一方法是发送一个函数列表并按顺序应用它们。有没有更好的办法?