【问题标题】:Anorm says no results were returned for select query preceded by inserts (PSQLException: No results were returned by the query)Anorm 表示插入之前的选择查询没有返回任何结果(PSQLException:查询没有返回任何结果)
【发布时间】:2013-05-02 04:07:15
【问题描述】:

我正在编写一个带有 Postgres 后端的 Play 2 应用程序。

我的代码有一个 sql 字符串,它是两个插入和一个选择的串联。然后当我尝试执行我的查询时,异常会爆炸并说我没有返回任何结果。我可以把它分成两个单独的查询,但是我会不必要地访问数据库吗?

sql 字符串非常简单。

val sql = """
        insert into gameconstants 
            ...
        values 
            ...;

        insert into gamevariables
            ...
        values
            ...;

        select lastval() as gameid;
  """  

然后,引发异常的代码只是尝试从查询中获取游戏 ID。这应该可以吗?

DB.withTransaction { implicit connection =>
  val gameid = SQL(sql).on(
    ... )()
    .map(row => row[Long]("gameid")).head
}  

这是错误[PSQLException:查询未返回任何结果。]

【问题讨论】:

  • 无论如何,您都将前往 DB。 PgJDBC 会将您的复合语句拆分并发送各个语句。查看网络流量或 PgJDBC 调试日志以查看详细信息。
  • 所以首选的方法实际上是通过网络发送多个语句?这不是一些容易实现的目标吗?
  • 正确的做法是创建一个 JDBC 批处理并发送该批处理。上次我检查 PgJDBC 的批处理支持时,无论如何都只是单独发送每个查询,但这可能最近发生了变化。是的,改进会很棒,但对于所有使用 PgJDBC 的人来说,几乎没有人为它做出贡献。
  • @Mark 也许你应该为此创建一个存储过程。这将减少网络使用量。

标签: postgresql scala anorm


【解决方案1】:

正如其他 cmets 所说,这是由向 JDBC 发出复合语句引起的。你有几个选择。

  1. 您可以执行 JDBC 批处理。正如上面 Craig 所说,这只是批量单独发送每个查询。

  2. 您可以使用此逻辑编写用户定义的函数/存储过程并在单个查询中调用。这具有将您的数据库逻辑封装在 API 后面的优点。缺点是如果没有太多关注,就很难维护存储过程和应用程序之间的契约。这是我在 Perl 中做一些工作的领域,但在 Java 中还没有做到。

  3. 您可以将查询折叠成两个(您的代码显示三个)。简单的解决方案是:

    val query1 = """
        insert into gameconstants 
            ...
        values 
            ...;"""
    
    
    val query2 = """
        insert into gamevariables
            ...
        values
            ...
        RETURNING * 
     """  
    

这会在一定程度上减少您的往返行程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-25
    • 2011-11-07
    • 1970-01-01
    • 2016-08-22
    • 2015-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多