我正在使用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);
}
提前致谢!
答案 0 :(得分:87)
如果传入变量,SQL Server要求您在top
的参数周围放置括号:
SELECT TOP (?)
答案 1 :(得分:19)
在我们的应用程序中,我们扩展了一个被忽视的SQLServerDialect
。更改为SQLServer2008Dialect
后,问题就消失了。
答案 2 :(得分:12)
将hibernate升级到5.x版并遇到了这个问题。不得不更新" hibernate.dialect"配置从org.hibernate.dialect.SQLServerDialect到org.hibernate.dialect.SQLServer2012Dialect。解决了这个问题!
Hibernate Doc参考: 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
答案 3 :(得分:1)
它也可能是由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:&#39; @ P5&#39;
附近的语法不正确问题实际上是平衡&#39;)&#39;最后遗漏,即正确的版本是
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')
答案 4 :(得分:0)
如果您使用自定义数据源,请添加属性:
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;
}
答案 5 :(得分:0)
如果您在spring-boot应用程序中使用Hibernate,可以使用以下配置属性设置hibernate.dialect
:
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2008Dialect
答案 6 :(得分:-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