【问题标题】:Single return type from multiple plpqsql functions using JOOQ使用 JOOQ 来自多个 plpqsql 函数的单一返回类型
【发布时间】:2016-02-26 04:51:21
【问题描述】:

我有许多 plpgsql 方法,它们都返回相同的自定义类型和其他函数,它们从其中一个表中返回相同的结构。

当 JOOQ 为这些生成源而不是返回与函数的返回类型匹配的表或 UDT 记录时,它会根据函数名称创建一个新的表记录。

这是唯一的行为吗?有没有办法从这些都具有相同返回类型的 plpgsql 调用中获取单个公共表记录或 POJO?

编辑:下面是两个返回类型为表格的函数和另外两个返回相同自定义类型的函数。表格和自定义类型最终与生成的函数代码无关。

DROP TABLE IF EXISTS author CASCADE;
CREATE TABLE author (
  id              bigint NOT NULL PRIMARY KEY,
  first_name      varchar(50),
  last_name       varchar(50) NOT NULL,
  date_of_birth   date,
  year_of_birth   integer,
  distinguished   boolean
);

DROP TABLE IF EXISTS book CASCADE;
CREATE TABLE book (
  id              bigint        NOT NULL PRIMARY KEY,
  author_id       bigint        NOT NULL,
  title           varchar(400)  NOT NULL,
  length          integer       NOT NULL,
  CONSTRAINT fk_book_author     FOREIGN KEY (author_id)   REFERENCES author(id)
);

DROP TYPE IF EXISTS authored_book CASCADE;
CREATE TYPE authored_book as (
  book_title           varchar(400),
  book_length          integer,
  author_first_name    varchar(50),
  author_last_name     varchar(50)
);


CREATE OR REPLACE FUNCTION get_my_favorite_authors(userId bigint) RETURNS SETOF author AS $_$
BEGIN
  return query select a.* from author a; -- where something or other
END
$_$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_editable_authors(adminId bigint) RETURNS SETOF author AS $_$
BEGIN
  return query select a.* from author a; -- where something or other
END
$_$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_short_books(maxLength integer) RETURNS SETOF authored_book AS $_$
BEGIN
  return query select b.title, b.length, a.first_name, a.last_name 
         from book b
         join author a on a.id = b.author_id
         where b.length <= maxLength;
END
$_$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION get_long_books(minLength integer) RETURNS SETOF authored_book AS $_$
BEGIN
  return query select b.title, b.length, a.first_name, a.last_name 
         from book b
         join author a on a.id = b.author_id
         where b.length >= minLength;
END
$_$ LANGUAGE plpgsql;

毫无疑问,我误解了一些东西,因为我什至无法正确调用该函数。这可以直接从作者表中工作:

public List<Author> jooqTest(Long companyId)
{
    return create.select().from(Tables.AUTHOR).fetchInto(Author.class);
}

但是我在下面尝试的任何其他使用例程的方法都会给我一个 ArrayIndexOutOfBoundsException

public List<Author> jooqTest2(Long userId)
{
    return create.select().from(Routines.getMyFavoriteAuthors(userId)).fetchInto(Author.class);
}

public List<GetMyFavoriteAuthors> jooqTest3(Long userId)
{
    return create.select().from(Routines.getMyFavoriteAuthors(userId)).fetchInto(GetMyFavoriteAuthors.class);
}

public List<GetMyFavoriteAuthorsRecord> jooqTest4(Long userId)
{
    return create.select().from(Routines.getMyFavoriteAuthors(userId)).fetchInto(GetMyFavoriteAuthorsRecord.class);
}

java.lang.ArrayIndexOutOfBoundsException: 0
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.setValue(CursorImpl.java:1483)
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(CursorImpl.java:1461)
at org.jooq.impl.CursorImpl$CursorIterator$CursorRecordInitialiser.operate(CursorImpl.java:1453)
at org.jooq.impl.RecordDelegate.operate(RecordDelegate.java:123)
at org.jooq.impl.CursorImpl$CursorIterator.fetchOne(CursorImpl.java:1416)
at org.jooq.impl.CursorImpl$CursorIterator.hasNext(CursorImpl.java:1384)
at org.jooq.impl.CursorImpl.fetch(CursorImpl.java:206)
at org.jooq.impl.CursorImpl.fetch(CursorImpl.java:181)
at org.jooq.impl.AbstractResultQuery.execute(AbstractResultQuery.java:260)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:341)
at org.jooq.impl.AbstractResultQuery.fetch(AbstractResultQuery.java:290)
at org.jooq.impl.AbstractResultQuery.fetchInto(AbstractResultQuery.java:763)
at org.jooq.impl.SelectImpl.fetchInto(SelectImpl.java:2731)

我似乎对一般的 postgresql 函数不太了解。

【问题讨论】:

  • 你能提供这样一个函数的例子吗?
  • 卢卡斯,谢谢光临。很抱歉浪费您的时间。我使用的是 3.5.3,而我的问题在 3.7.1 中消失了。没有意识到我已经过时了。
  • 很高兴升级对您有用。是的,我们同时实施了很多错误修正,尤其是在这方面。他们仍然需要 3.5.x 补丁版本...

标签: postgresql stored-procedures plpgsql jooq


【解决方案1】:

我能够完全按照我的需要做:

public List<Author> jooqTest2(Long userId)
{
    return create.select().from(Routines.getMyFavoriteAuthors(userId)).fetchInto(Author.class);
}

它在 3.5.3 版本中无法正常工作,但最新的 3.7.1 可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 2014-04-10
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多