【问题标题】:MS SQL Exception: Incorrect syntax near '@P0'MS SQL 异常:'@P0' 附近的语法不正确
【发布时间】:2011-10-25 17:06:20
【问题描述】:

我正在使用 MS SQL 查询数据库,由于某种原因,我收到以下错误:com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '@P0' 即使这个“P0”不在我的语法中...

我读到有人遇到过同样的问题,但他们使用的是存储过程,我没有使用它,所以我看不出他的解决方案对我有什么用。 (他的解决方案是在过程调用周围添加大括号 {}。

无论如何,下面我已经粘贴了相关代码。真的希望有人可以帮助我解决这个问题,非常沮丧。

PreparedStatement stmt = null;
Connection conn = null;    

String sqlQuery = "SELECT TOP ? \n"+
                              "z.bankAccountNo, \n"+
                              "z.statementNo, \n"+
                              "z.transactionDate, \n"+
                              "z.description, \n"+
                              "z.amount, \n"+
                              "z.guid \n"+
                              "FROM \n"+
                              "( \n"+
                              "select  \n"+
                              "ROW_NUMBER() OVER (ORDER BY x.transactionDate, x.statementNo) AS RowNumber, \n"+
                              "x.transactionDate, \n"+
                              "x.statementNo, \n"+
                              "x.description, \n"+
                              "x.amount, \n"+
                              "x.bankAccountNo, \n"+
                              "x.guid \n"+
                              "FROM \n"+
                              "( \n"+
                              "SELECT  \n"+
                              "a.bankAccountNo,  \n"+
                              "a.statementNo,  \n"+
                              "a.transactionDate, \n"+
                              "a.description,  \n"+
                              "a.amount,  \n"+
                              "a.guid  \n"+
                              "FROM BankTransactions as a  \n"+
                              "LEFT OUTER JOIN BankTransactionCategories as b  \n"+
                              "ON a.category = b.categoryCode  \n"+
                              "WHERE b.categoryCode is null \n"+
                              ") as x \n"+
                              ") as z \n"+
                              "WHERE (z.RowNumber >= ?)";

stmt = conn.prepareStatement(sqlQuery);
stmt.setInt(1, RowCountToDisplay);
stmt.setInt(2, StartIndex);
ResultSet rs = null;
try{
    rs = stmt.executeQuery();
} catch (Exception Error){
    System.out.println("Error: "+Error);
}

提前致谢!

【问题讨论】:

  • '@P0' 是你的 rowcounttodisplay 参数
  • 你能提供导致错误的实际sql吗?您似乎没有正确提供RowCountToDisplay

标签: java sql jdbc


【解决方案1】:

按以下方式调用过程

@Override
public List<Rep_Holdings> getHoldingsReport(
        int pid
)
{
    List<Rep_Holdings> holdings = null;

    Session sess = sFac.getCurrentSession();
    if (sess != null && pid > 0)
    {
        @SuppressWarnings(
            "rawtypes"
        )
        Query query = sess.createSQLQuery(
                "{CALL GetHoldingsforPF(:pid)}").addEntity(Rep_Holdings.class);
        query.setParameter("pid", pid);

        @SuppressWarnings(
            "rawtypes"
        )
        List result = query.getResultList();
        if (result != null)
        {
            if (result.size() > 0)
            {
                holdings = new ArrayList<Rep_Holdings>();
                for (int i = 0; i < result.size(); i++)
                {
                    Rep_Holdings holding = (Rep_Holdings) result.get(i);
                    holdings.add(holding);
                }
            }
        }
    }

    return holdings;
}

SQL Server 中的相同过程

ALTER PROCEDURE [dbo].[GetHoldingsforPF]
    @pid int
AS
BEGIN
SET NOCOUNT ON;
        -- Insert statements for procedure here

        declare @totalPFInv decimal(15,2);

    set @totalPFInv =  ( select  sum(totalInvestment) from Holdings where pid = @pid );

    Select hid,
           pid,
           scCode,
           numUnits,
           avgPPU,
           adjPPU,
           totalInvestment,
           cast ( (totalInvestment/@totalPFInv)*100 as decimal(10,1)) as perPF,
           totalDiv,
           cast ( (totalDiv/totalInvestment)*100 as decimal(10,1)) as divY
           from Holdings
           where pid = @pid
END

【讨论】:

  • 您似乎回答的问题与此处提出的问题不同。 OP 没有使用存储过程,所以你的回答没有意义。
【解决方案2】:

如果您在 spring-boot 应用程序中使用 Hibernate,您可以使用以下配置属性设置 hibernate.dialect:

spring.jpa.database-platform=org.hibernate.dialect.SQLServer2008Dialect

【讨论】:

  • 适用于 Spring Roo。只需在 roo 脚本末尾提供 property add --key spring.jpa.properties.hibernate.dialect --value org.hibernate.dialect.SQLServer2012Dialect。
【解决方案3】:

如果您使用的是自定义数据源,请添加属性:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect

在 application.properties 中不起作用。

您必须将属性添加为数据源 bean 中的属性映射:

  @Bean
public LocalContainerEntityManagerFactoryBean sqlServerEntityManagerFactory() {
    HashMap<String, String> properties = new HashMap<>();
    properties.put("hibernate.dialect", "org.hibernate.dialect.SQLServer2012Dialect");

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(sqlServerDataSource());
    factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    factoryBean.setJpaPropertyMap(properties);
    return factoryBean;
}

【讨论】:

    【解决方案4】:

    将休眠升级到 5.x 版并遇到此问题。必须将“hibernate.dialect”配置从 org.hibernate.dialect.SQLServerDialect 更新为 org.hibernate.dialect.SQLServer2012Dialect。修复了问题!

    Hibernate 文档参考: https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/session-configuration.html#configuration-programmatic

    Hibernate Jira 问题: https://hibernate.atlassian.net/browse/HHH-10032

    【讨论】:

      【解决方案5】:

      在我们的应用程序中,我们扩展了一个已废弃的SQLServerDialect。改成SQLServer2008Dialect后问题就消失了。

      【讨论】:

      • 我在迁移到 Spring Boot 1.4 后也遇到了同样的情况,因此有了新的 Hibernate 版本
      • 我在使用PageRequest 时得到了这个。根据@Andomar 的回答,我猜测它是使用不带括号的“顶部”实现的。正如您所说,从SQLServerDialect(在我的情况下为 2012 年)更新似乎可以解决问题。显然,这是 SQL Server 2005 中的一个变化:dotnetfunda.com/articles/show/59/…
      【解决方案6】:

      这也可能是由您的 SQL 中的语法错误引起的,就像我一样

      select * from drivel d where exists (select * from drivel where d.id = drivel.id and drivel.start_date < '2015-02-05' AND '2015-02-05' < drivel.end_date) OR exists (select * from drivel where d.id = drivel.id and drivel.start_date < '2015-02-05' AND '2015-02-05' < drivel.end_date) OR exists (select * from drivel where d.id = drivel.id and '2015-02-05' < drivel.start_date and drivel.end_date < '2015-02-05'
      

      留言

      com.microsoft.sqlserver.jdbc.SQLServerException:“@P5”附近的语法不正确

      问题实际上是最后缺少平衡')',即正确的版本是

      select * from drivel d where exists (select * from drivel where d.id = drivel.id and drivel.start_date < '2015-02-05' AND '2015-02-05' < drivel.end_date) OR exists (select * from drivel where d.id = drivel.id and drivel.start_date < '2015-02-05' AND '2015-02-05' < drivel.end_date) OR exists (select * from drivel where d.id = drivel.id and '2015-02-05' < drivel.start_date and drivel.end_date < '2015-02-05')
      

      【讨论】:

        【解决方案7】:

        如果你传入一个变量,SQL Server 要求你在 top 的参数周围加上括号:

        SELECT TOP (?)
        

        【讨论】:

        • 谢谢!这就是问题所在……为此苦苦挣扎了好几个小时。总是一件小事不是吗...再次感谢。
        • 此错误也可能出现在INSERT 语法错误绑定查询中。 @P 字符后面的数字可以指示哪个参数产生错误(@P3 第三个参数,...)。
        • 在没有 SO 的情况下可能花费在此问题上的时间:3-8 小时在此问题上花费的时间 SO:55 秒。谢谢!
        • 没错!谢谢。
        • 虽然这是正确的,但我发现解决方案是@Tomasz Godziński 答案
        猜你喜欢
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2017-02-07
        • 1970-01-01
        • 2018-06-26
        相关资源
        最近更新 更多