2017-09-26 56 views
0

我试图调用SQL查询(Oracle数据库)来更新一个表中的列,当链接表中的某些列具有某些值时。我的语法在一般的代码工作正常,但在我的单元测试,我得到一个“BadSQLGrammarException”:SQL查询在代码中正常工作,而不是在测试中

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [UPDATE (SELECT ex.STATUS FROM BRRS_EXECUTION ex, BRRS_DEMANDE dem WHERE dem.ID_DEMANDE=ex.ID_DEMANDE AND dem.UTILISATEUR=? AND dem.PROFIL=? AND dem.REGION=? AND dem.REGIME=? AND ex.ID_EXECUTION=?) SET STATUS=?]; nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "UPDATE ([*]SELECT EX.STATUS FROM BRRS_EXECUTION EX, BRRS_DEMANDE DEM WHERE DEM.ID_DEMANDE=EX.ID_DEMANDE AND DEM.UTILISATEUR=? AND DEM.PROFIL=? AND DEM.REGION=? AND DEM.REGIME=? AND EX.ID_EXECUTION=?) SET STATUS=? "; expected "identifier"; SQL statement: 
UPDATE (SELECT ex.STATUS FROM BRRS_EXECUTION ex, BRRS_DEMANDE dem WHERE dem.ID_DEMANDE=ex.ID_DEMANDE AND dem.UTILISATEUR=? AND dem.PROFIL=? AND dem.REGION=? AND dem.REGIME=? AND ex.ID_EXECUTION=?) SET STATUS=? [42001-190] 
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649) 
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870) 
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:894) 
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:287) 
    at fr.cnamts.brrsm.services.app.majRequeteSAS.repository.impl.RequeteSASRepositoryOracle.deleteRequeteSAS(RequeteSASRepositoryOracle.java:191) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy46.deleteRequeteSAS(Unknown Source) 
    at fr.cnamts.brrsm.services.app.majRequeteSAS.repository.RequeteSASRepositoryTest.testSupprimerRequete(RequeteSASRepositoryTest.java:157) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55) 
    at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "UPDATE ([*]SELECT EX.STATUS FROM BRRS_EXECUTION EX, BRRS_DEMANDE DEM WHERE DEM.ID_DEMANDE=EX.ID_DEMANDE AND DEM.UTILISATEUR=? AND DEM.PROFIL=? AND DEM.REGION=? AND DEM.REGIME=? AND EX.ID_EXECUTION=?) SET STATUS=? "; expected "identifier"; SQL statement: 
UPDATE (SELECT ex.STATUS FROM BRRS_EXECUTION ex, BRRS_DEMANDE dem WHERE dem.ID_DEMANDE=ex.ID_DEMANDE AND dem.UTILISATEUR=? AND dem.PROFIL=? AND dem.REGION=? AND dem.REGIME=? AND ex.ID_EXECUTION=?) SET STATUS=? [42001-190] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) 
    at org.h2.message.DbException.getSyntaxError(DbException.java:205) 
    at org.h2.command.Parser.readIdentifierWithSchema(Parser.java:3065) 
    at org.h2.command.Parser.readTableOrView(Parser.java:5270) 
    at org.h2.command.Parser.readSimpleTableFilter(Parser.java:764) 
    at org.h2.command.Parser.parseUpdate(Parser.java:707) 
    at org.h2.command.Parser.parsePrepared(Parser.java:454) 
    at org.h2.command.Parser.parse(Parser.java:304) 
    at org.h2.command.Parser.parse(Parser.java:276) 
    at org.h2.command.Parser.prepareCommand(Parser.java:241) 
    at org.h2.engine.Session.prepareLocal(Session.java:460) 
    at org.h2.engine.Session.prepareCommand(Session.java:402) 
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1188) 
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:72) 
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:276) 
    at fr.cnamts.brrsm.services.app.utils.test.jdbc.UnclosableConnection.prepareStatement(UnclosableConnection.java:58) 
    at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.createPreparedStatement(PreparedStatementCreatorFactory.java:238) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:627) 
    ... 50 more 

显然问题出在括号和选择之间。看起来它不接受“UPDATE(SELECT ...”)语法,如果你想要更多这个,这里是查询(对列和表名称使用常量)以及它使用的函数:

private static final String UPDATE_REQUETE_SAS_SQL = "UPDATE (SELECT ex."+ COL_STATUS + 
     " FROM " + TABLE_BRRS_EXECUTION + " ex, " + TABLE_BRRS_DEMANDE + " dem " 
     + "WHERE dem." + COL_ID_DEMANDE + "=ex." + COL_ID_DEMANDE + " " 
     + "AND dem." + COL_UTILISATEUR + "=:UTILISATEUR " 
     + "AND dem." + COL_PROFIL + "=:PROFIL " 
     + "AND dem." + COL_REGION + "=:REGION " 
     + "AND dem." + COL_REGIME + "=:REGIME " 
     + "AND ex." + COL_ID_EXECUTION + "=:ID_EXECUTION)" 
     + " SET " + COL_STATUS +"=:STATUS"; 

@Override 
    public void deleteRequeteSAS(RequeteSASEntity requeteSASEntity, String user, String region, String profil, String regime) { 
     // affectation des parametres nommés 
     final SqlParameterSource params = new MapSqlParameterSource() 
       .addValue(COL_STATUS, STATUS_SUPPRIME) 
       .addValue(COL_ID_EXECUTION, requeteSASEntity.getIdExecution()) 
       .addValue(COL_UTILISATEUR, user) 
       .addValue(COL_REGION, region) 
       .addValue(COL_PROFIL, profil) 
       .addValue(COL_REGIME, regime); 


     // execution de l'update 
     jdbcTemplate.update(UPDATE_REQUETE_SAS_SQL, params); 


    } 

最后,这里是我的测试:

@Test 公共无效testSupprimerRequete()抛出IOException异常{

String mockUser = "QUAREFMETIER-00001"; 
    String mockRegion = "99"; 
    String mockProfil = "030"; 
    String mockRegime = "01"; 

    List<RequeteSASEntity> listReqInit = new ArrayList<RequeteSASEntity>(); 
    listReqInit.add(requeteSASJdbc1); 
    listReqInit.add(requeteSASJdbc2); 

    requeteSASRepository.deleteRequeteSAS(requeteSASJdbc1, mockUser, mockRegion, mockProfil, mockRegime); 

    assertTrue(!listReqInit.isEmpty()); 
    assertTrue(listReqInit.get(1).getStatus() == 7); 
} 

当然我的测试中,我使用了类似的XML定义的基础上,用同样的结构

那么我的查询中的问题在哪里,我该如何纠正它?或者,如果它是与更新问题(SELECT ...语法,我怎么能有一个类似的查询这将工作? 谢谢。

+0

也许看到https://stackoverflow.com/questions/2334712/how-do-i-update-from-a-select-in-sql-server –

+0

一般来说,你不能从'UPDATE(SELECT ..你必须以'UPDATE TableName ...'开头毕竟,你正在更新表 - 你没有更新你的'select'语句。 –

+1

@DM一些数据库系统(包括SQL标准)考虑子查询是虚拟表,并允许在某些条件下更新此虚拟表。可能在测试中使用的数据库不允许它,而实际的数据库却可以。 –

回答

0
Update TableName Set COL_STATUS =(
SELECT EX.STATUS FROM BRRS_EXECUTION EX, BRRS_DEMANDE DEM WHERE 
DEM.ID_DEMANDE=EX.ID_DEMANDE AND DEM.UTILISATEUR=? AND DEM.PROFIL=? AND 
DEM.REGION=? AND DEM.REGIME=? AND EX.ID_EXECUTION=?); 

您可以用这种方式修改您的查询。

+0

哼,不,它不是同一个查询。当两个表的其他列有给定的条件时,我想将COL_STATUS设置为绝对值(= 7 - >:STATUS)。你们不这样做。 – Djbapt

相关问题