【问题标题】:query with 2 in clauses (Derby, JPA): Subquery is only allowed to return a single column带有 2 个 in 子句的查询(Derby,JPA):子查询只允许返回单个列
【发布时间】:2015-04-21 16:54:55
【问题描述】:

我在这个查询上有一个错误:

SELECT p FROM Polizza p  WHERE p.nrPolizza IN ( 
      SELECT r.nrPolizza FROM Rate r WHERE r.idRate IN ( 
           SELECT q.iDRata FROM Pagamenti q WHERE 
                     q.pagante.codiceFiscale LIKE :pagante OR 
                     q.pagante.nome LIKE :pagante OR 
                     q.pagante.cognome LIKE :pagante 
           )
      )

我正在使用 java8、jpa eclipse 持久性和 Derby 数据库。 错误说“子查询只允许返回一个列。”但是在IN子句的select中,只有一列已经被选中。

我该如何解决这个问题? 谢谢

错误是:

    [EL Warning]: 2015-04-22 10:29:31.937--UnitOfWork(782315816)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: La subquery può restituire solo una colonna singola.
Error Code: 30000
Call: SELECT t0.NRPOLIZZA, t0.DATAINIZIO, t0.NOTE, t0.SCADCONTRATTO, t0.Beneficiario, t0.Contraente, t0.Frazionamento, t0.Proprietario, t0.StatoPolizza, t0.Tipo, t0.Veicolo FROM assicurazionedb.POLIZZA t0 WHERE t0.NRPOLIZZA IN (SELECT t1.NRPOLIZZA, t1.DATAINIZIO, t1.NOTE, t1.SCADCONTRATTO, t1.Beneficiario, t1.Contraente, t1.Frazionamento, t1.Proprietario, t1.StatoPolizza, t1.Tipo, t1.Veicolo FROM assicurazionedb.RATE t2 LEFT OUTER JOIN assicurazionedb.POLIZZA t1 ON (t1.NRPOLIZZA = t2.NrPolizza) WHERE t2.IDRATE IN (SELECT t3.IDRATE, t3.ABBUONO, t3.IMPORTORATA, t3.SALDATA, t3.SCADRATA, t3.TIPORATA, t3.NrPolizza FROM assicurazionedb.PAGAMENTI t4 LEFT OUTER JOIN assicurazionedb.RATE t3 ON (t3.IDRATE = t4.IDRata), assicurazionedb.ANAGRAFICA t5 WHERE (((t5.CODICEFISCALE LIKE ? OR t5.NOME LIKE ?) OR t5.COGNOME LIKE ?) AND (t5.CODICEFISCALE = t4.Pagante))))
    bind => [3 parameters bound]
Query: ReadAllQuery(referenceClass=Polizza sql="SELECT t0.NRPOLIZZA, t0.DATAINIZIO, t0.NOTE, t0.SCADCONTRATTO, t0.Beneficiario, t0.Contraente, t0.Frazionamento, t0.Proprietario, t0.StatoPolizza, t0.Tipo, t0.Veicolo FROM assicurazionedb.POLIZZA t0 WHERE t0.NRPOLIZZA IN (SELECT t1.NRPOLIZZA, t1.DATAINIZIO, t1.NOTE, t1.SCADCONTRATTO, t1.Beneficiario, t1.Contraente, t1.Frazionamento, t1.Proprietario, t1.StatoPolizza, t1.Tipo, t1.Veicolo FROM assicurazionedb.RATE t2 LEFT OUTER JOIN assicurazionedb.POLIZZA t1 ON (t1.NRPOLIZZA = t2.NrPolizza) WHERE t2.IDRATE IN (SELECT t3.IDRATE, t3.ABBUONO, t3.IMPORTORATA, t3.SALDATA, t3.SCADRATA, t3.TIPORATA, t3.NrPolizza FROM assicurazionedb.PAGAMENTI t4 LEFT OUTER JOIN assicurazionedb.RATE t3 ON (t3.IDRATE = t4.IDRata), assicurazionedb.ANAGRAFICA t5 WHERE (((t5.CODICEFISCALE LIKE ? OR t5.NOME LIKE ?) OR t5.COGNOME LIKE ?) AND (t5.CODICEFISCALE = t4.Pagante))))")
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

我尝试执行另一个查询,跳过表“anagrafica”的点表示法,但我得到了同样的错误。

SELECT p FROM Polizza p  WHERE p.nrPolizza IN ( 
   SELECT r.nrPolizza FROM Rate r WHERE r.idRate IN ( 
        SELECT q.iDRata FROM Pagamenti q WHERE q.pagante IN (
             SELECT a.codiceFiscale FROM Anagrafica a WHERE 
                      a.codiceFiscale LIKE :pagante OR 
                      a.nome LIKE :pagante OR 
                      a.cognome LIKE :pagante
              )
         )
 )

错误:

[EL Warning]: 2015-04-22 11:04:47.384--UnitOfWork(939627839)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: La subquery può restituire solo una colonna singola.
Error Code: 30000
Call: SELECT t0.NRPOLIZZA, t0.DATAINIZIO, t0.NOTE, t0.SCADCONTRATTO, t0.Beneficiario, t0.Contraente, t0.Frazionamento, t0.Proprietario, t0.StatoPolizza, t0.Tipo, t0.Veicolo FROM assicurazionedb.POLIZZA t0 WHERE t0.NRPOLIZZA IN (SELECT t1.NRPOLIZZA, t1.DATAINIZIO, t1.NOTE, t1.SCADCONTRATTO, t1.Beneficiario, t1.Contraente, t1.Frazionamento, t1.Proprietario, t1.StatoPolizza, t1.Tipo, t1.Veicolo FROM assicurazionedb.RATE t2 LEFT OUTER JOIN assicurazionedb.POLIZZA t1 ON (t1.NRPOLIZZA = t2.NrPolizza) WHERE t2.IDRATE IN (SELECT t3.IDRATE, t3.ABBUONO, t3.IMPORTORATA, t3.SALDATA, t3.SCADRATA, t3.TIPORATA, t3.NrPolizza FROM assicurazionedb.PAGAMENTI t4 LEFT OUTER JOIN assicurazionedb.RATE t3 ON (t3.IDRATE = t4.IDRata) WHERE t4.Pagante IN (SELECT t5.CODICEFISCALE.t5.CODICEFISCALE FROM assicurazionedb.ANAGRAFICA t5 WHERE ((t5.CODICEFISCALE LIKE ? OR t5.NOME LIKE ?) OR t5.COGNOME LIKE ?))))
    bind => [3 parameters bound]
Query: ReadAllQuery(referenceClass=Polizza sql="SELECT t0.NRPOLIZZA, t0.DATAINIZIO, t0.NOTE, t0.SCADCONTRATTO, t0.Beneficiario, t0.Contraente, t0.Frazionamento, t0.Proprietario, t0.StatoPolizza, t0.Tipo, t0.Veicolo FROM assicurazionedb.POLIZZA t0 WHERE t0.NRPOLIZZA IN (SELECT t1.NRPOLIZZA, t1.DATAINIZIO, t1.NOTE, t1.SCADCONTRATTO, t1.Beneficiario, t1.Contraente, t1.Frazionamento, t1.Proprietario, t1.StatoPolizza, t1.Tipo, t1.Veicolo FROM assicurazionedb.RATE t2 LEFT OUTER JOIN assicurazionedb.POLIZZA t1 ON (t1.NRPOLIZZA = t2.NrPolizza) WHERE t2.IDRATE IN (SELECT t3.IDRATE, t3.ABBUONO, t3.IMPORTORATA, t3.SALDATA, t3.SCADRATA, t3.TIPORATA, t3.NrPolizza FROM assicurazionedb.PAGAMENTI t4 LEFT OUTER JOIN assicurazionedb.RATE t3 ON (t3.IDRATE = t4.IDRata) WHERE t4.Pagante IN (SELECT t5.CODICEFISCALE.t5.CODICEFISCALE FROM assicurazionedb.ANAGRAFICA t5 WHERE ((t5.CODICEFISCALE LIKE ? OR t5.NOME LIKE ?) OR t5.COGNOME LIKE ?))))")
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)

我在数据库上尝试过的查询效果很好:

SELECT * FROM Polizza p  WHERE p.nrPolizza IN (
     SELECT r.nrPolizza FROM Rate r WHERE r.idRate IN (
         SELECT q.iDRata FROM Pagamenti q WHERE q.pagante IN (
               SELECT a.codicefiscale FROM Anagrafica a WHERE
                      a.codicefiscale LIKE 'Matteo' OR
                      a.nome LIKE 'Matteo' OR 
                      a.cognome LIKE 'Matteo'
               )
         )
      )

编辑1: 编辑别名 编辑2: 已编辑的查询 编辑3: 解决了。​​

您好,我已经解决了这个问题:如果在数据库中执行查询运行良好,那么 Jpa 查询中存在错误: 'r.nrPolizza' 它实际上是一个 Polizza 类型的对象,所以为了比较 'p.nrPolizza'(整数)它必须是:'r.nrPolizza.nrPolizza'。 所以查询

SELECT p FROM Polizza p  WHERE p.nrPolizza IN ( 
       SELECT r.nrPolizza.nrPolizza FROM Rate r WHERE r.idRate IN ( 
            SELECT q.iDRata.idRate FROM Pagamenti q WHERE q.pagante.codiceFiscale IN (
                 SELECT a.codiceFiscale FROM Anagrafica a WHERE 
                          a.codiceFiscale LIKE :pagante OR 
                          a.nome LIKE :pagante OR 
                          a.cognome LIKE :pagante
                  )
             )
     )

SELECT p FROM Polizza p  WHERE p.nrPolizza IN  
       (SELECT DISTINCT q.iDRata.nrPolizza.nrPolizza FROM Pagamenti q WHERE q.pagante IN  
          (SELECT a FROM Anagrafica a WHERE 
               a.codiceFiscale LIKE :pagante OR 
               a.nome LIKE :pagante OR a.cognome LIKE :pagante
          )
       )

效果很好。

【问题讨论】:

  • 向我们展示您的实体。

标签: sql jpa derby


【解决方案1】:

错误中的查询与您的示例中的查询不匹配。如果您阅读了错误,它引用了一个看起来像

的查询

SELECT ... WHERE t0.NRPOLIZZA IN ( SELECT t1.NRPOLIZZA, t1.DATAINIZIO, ...

我不确定您的代码是什么样的,但我猜您正在查看错误的代码。您是否在代码中的某处使用了“*”?

** 另一个想法,您使用了两次相同的别名。尽量不要使用“p”两次。我不知道德比,但值得一试...

【讨论】:

  • 嗨,是的,这是我在代码中使用的唯一查询:我在执行 'u = em.createQuery(query);' 之前也会打印它.我也更改了别名,但这并不能解决问题。在我看来,当 JPA 引擎翻译查询时出现错误,而不是只选择一列,而是选择了所有表。
  • 哇,很高兴你能解决它。我不确定我能猜到这一点。 :-D
猜你喜欢
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-30
  • 2017-07-20
  • 1970-01-01
相关资源
最近更新 更多