“?”附近的语法不正确:Nhibernate生成的查询

时间:2012-05-22 06:03:13

标签: nhibernate nhibernate-criteria

我在使用Nhbernate中的位置参数时遇到问题。

Criteria GroupProperty正在发出包含命名变量和位置变量的SQL。

本声明:

session.CreateCriteria(typeof(MatchStageFrom))
                .SetProjection(Projections.GroupProperty(
                    Projections.SqlFunction("substring", NHibernateUtil.String, Projections.Property("LastName"), Projections.Constant(0), Projections.Constant(1))
                    )
                );

正在生成这个SQL:

SELECT substring(this_.LAST_NAME, @p0, @p1) as y0_ FROM MATCH_STAGING_FROM this_ GROUP BY substring(this_.LAST_NAME, ?, ?)

导致SQL错误:

Incorrect syntax near '?'.

could not execute query
[ SELECT substring(this_.LAST_NAME, @p0, @p1) as y0_ FROM MATCH_STAGING_FROM this_ GROUP BY substring(this_.LAST_NAME, ?, ?) ]
Positional parameters: #0>0 #1>1 #2>0 #3>1
[SQL: SELECT substring(this_.LAST_NAME, @p0, @p1) as y0_ FROM MATCH_STAGING_FROM this_ GROUP BY substring(this_.LAST_NAME, ?, ?)]

我该怎么做才能解决它?

3 个答案:

答案 0 :(得分:0)

它看起来像NHibernate中的一个错误,但是如果你只是想要那些结果,你可以通过使用Projections.Distinct而不是Projections.GroupProperty得到相同的结果,即:

session.CreateCriteria(typeof(MatchStageFrom))
            .SetProjection(Projections.Distinct(
                Projections.SqlFunction("substring", NHibernateUtil.String, 
                    Projections.Property("LastName"), 
                    Projections.Constant(0), 
                    Projections.Constant(1))
                )
            );

或者,如果您选择的不仅仅是名称的第一个字符,那么您可以使用子选择来使其工作

答案 1 :(得分:0)

我遇到了Projections.SqlFunction("concat" ...)的类似问题。最后,我使用Projections.SqlProjection(...)代替了它。我不喜欢这个答案,因为我认为它可能不太便携,但它对我有用。

答案 2 :(得分:0)

解决方法

使用group by和SqlFunction参数时,NHibernate中存在一个错误。 “如果应用Projections.GroupProperty(customProjection),则投影中的参数仅发送一次(对于SELECT子句),而GROUP BY子句中的参数在查询中是位置和缺失的。 “。 (see

进入相同的bug并通过在运行时向NHibernate添加自定义SQL函数来解决它, (see

变通方法将常量参数移出Projections.SqlFunction调用并进入自定义函数的定义(“year_week”)。

老失败:

Projections.GroupProperty(
   Projections.Cast(NHibernateUtil.AnsiString,
      Projections.SqlFunction("to_char", NHibernateUtil.AnsiChar,
         Projections.Property(() => myAlias.Date),
         Projections.Constant("IYYYIW") // Turns into "?" in group by
      )
   )
)

解决方法:

Projections.GroupProperty(
   Projections.Cast(NHibernateUtil.AnsiString,
      Projections.SqlFunction("year_week", NHibernateUtil.AnsiChar,
         Projections.Property(() => myAlias.Date)
         // constant moved to function definition
      )
    )
)

功能“year_week”定义如下:

DialectExtensions.RegisterFunction(sessionFactory, "year_week", new SQLFunctionTemplate(NHibernateUtil.String, "TO_CHAR(?1,'IYYYIW')"));