删除时权限不足
Insufficient privileges when deleting
我有一个 spring-批处理应用程序。
测试以某种方式失败并出现以下错误:
2019-04-26 09:54:56 ERROR o.s.batch.core.step.AbstractStep - Encountered an error executing step stepCleanTrades in job tradesLoadJob
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID JOIN T_UPSTREAM_SYSTEM S ON S.ID = T.UP_SYS_ID WHERE trunc(T.RECORD_DATE) = trunc(?) AND S.NAME = ?)]; nested exception is java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:91) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:866) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:890) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:287) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:292) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at com.bank.dept.app.batch.dao.impl.TradesDaoImpl.deleteCurrentTrades(TradesDaoImpl.java:32) ~[classes/:na]
at com.bank.dept.app.batch.tasklet.CleanCurrentTradesTasklet.execute(CleanCurrentTradesTasklet.java:17) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at $Proxy66.execute(Unknown Source) ~[na:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doInChunkContext(TaskletStep.java:271) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at $Proxy32.run(Unknown Source) [na:na]
at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:152) [spring-batch-test-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:141) [spring-batch-test-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at com.bank.dept.app.dml.cc.test.IntegrationExistingMessageTest.launchAllSteps(IntegrationExistingMessageTest.java:144) [test-classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:205) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:873) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:866) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
... 83 common frames omitted
作业定义为:
<beans:bean id="cleanCurrentTradesTasklet"
class="com.bank.dept.app.batch.tasklet.CleanCurrentTradesTasklet" scope="step">
</beans:bean>
<batch:job id="tradesLoadJob" xmlns="http://www.springframework.org/schema/batch">
<batch:step id="stepCleanTrades" >
<batch:tasklet ref="cleanCurrentTradesTasklet" allow-start-if-complete="true" />
</batch:step>
</batch:job>
工作class:
public class CleanCurrentTradesTasklet implements Tasklet {
@Autowired
TradesDao tradesDao;
@Override
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
tradesDao.deleteCurrentTrades();
return RepeatStatus.FINISHED;
}
}
测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:app-dml-subscriber-top-level-test.xml" })
@ActiveProfiles(profiles={"local","notification-no-ssl","no-stock"})
public class IntegrationExistingMessageTest {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void launchAllSteps() throws Exception {
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
}
}
道 class :
@Repository("tradesDao")
public class TradesDaoImpl implements TradesDao {
private static final String UPSTREAM_SYSTEM = "GCAL";
private static final String DELETE_CURRENT_TRADES = "DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID JOIN T_UPSTREAM_SYSTEM S ON S.ID = T.UP_SYS_ID WHERE trunc(T.RECORD_DATE) = trunc(:date) AND S.NAME = :upstream)";
private static final String DELETE_TEST = "DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID WHERE trunc(T.RECORD_DATE) = trunc(:date) AND T.SYS_REF = 'DH1910800009')";
@Override
public void deleteCurrentTrades() {
Date today = new Date(new java.util.Date().getTime());
Map<String, Object> params = new HashMap<>(2);
params.put("date", today);
params.put("upstream", UPSTREAM_SYSTEM);
this.getJdbcTemplate().update(DELETE_CURRENT_TRADES, params);
}
}
我的目标是从 T_TRADE 和 T_CASH_FLOW tables
中删除数据
当我将 deleteCurrentTrades() 更改为以下代码时,我没有出现异常:
@Override
public void deleteCurrentTrades() {
Date today = new Date(new java.util.Date().getTime());
Map<String, Object> params = new HashMap<>(1);
params.put("date", today);
this.getJdbcTemplate().update(DELETE_TEST, params);
}
看来问题出在 T_UPSTREAM_SYSTEM table 上的赠款,如下所示:
+-----------+------------------+-----------+-----------+-------------------+
| Privilege | Grantee | Grantable | Grantor | Object Name |
+-----------+------------------+-----------+-----------+-------------------+
| SELECT | APP_MONITORING | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_CONSULT | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_WAS | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | BATCH_USER | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_FR_USER | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_CONSULT_LVL3 | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
+-----------+------------------+-----------+-----------+-------------------+
使用的用户是BATCH_USER
我的查询有什么问题?
似乎 T_TRADE
和 T_CASH_FLOW
是 BATCH_USER
架构的 table,而 T_UPSTREAM_SYSTEM
是 [=16 的 table =]
如果您已授予(SQL> conn APP_OWNER SQL> grant delete on T_UPSTREAM_SYSTEM to BATCH_USER
)对BATCH_USER
的删除权限,您可以通过:
删除所需的记录
DELETE APP_OWNER.T_UPSTREAM_SYSTEM SS
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND S.ID = SS.ID );
架构名称 APP_OWNER.
为 T_UPSTREAM_SYSTEM
作为前缀。
编辑: (我忘了你想从其他 table 中删除的点,而不是我上面提到的那个).因此,使用以下单独的删除语句:
DELETE T_TRADE TT
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND T.ID = TT.ID );
DELETE T_CASH_FLOW FF
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND F.TRADE_ID = FF.TRADE_ID );
我有一个 spring-批处理应用程序。
测试以某种方式失败并出现以下错误:
2019-04-26 09:54:56 ERROR o.s.batch.core.step.AbstractStep - Encountered an error executing step stepCleanTrades in job tradesLoadJob
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID JOIN T_UPSTREAM_SYSTEM S ON S.ID = T.UP_SYS_ID WHERE trunc(T.RECORD_DATE) = trunc(?) AND S.NAME = ?)]; nested exception is java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:91) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:645) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:866) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:890) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:287) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:292) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at com.bank.dept.app.batch.dao.impl.TradesDaoImpl.deleteCurrentTrades(TradesDaoImpl.java:32) ~[classes/:na]
at com.bank.dept.app.batch.tasklet.CleanCurrentTradesTasklet.execute(CleanCurrentTradesTasklet.java:17) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at $Proxy66.execute(Unknown Source) ~[na:na]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doInChunkContext(TaskletStep.java:271) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.5.RELEASE.jar:3.0.5.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) [spring-aop-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at $Proxy32.run(Unknown Source) [na:na]
at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:152) [spring-batch-test-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.test.JobLauncherTestUtils.launchJob(JobLauncherTestUtils.java:141) [spring-batch-test-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at com.bank.dept.app.dml.cc.test.IntegrationExistingMessageTest.launchAllSteps(IntegrationExistingMessageTest.java:144) [test-classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_11]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_11]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_11]
at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_11]
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) [spring-test-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]
Caused by: java.sql.SQLSyntaxErrorException: ORA-01031: insufficient privileges
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:205) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350) ~[ojdbc6-11.2.0.1.0.jar:11.2.0.1.0]
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105) ~[commons-dbcp-1.4.jar:1.4]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:873) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.doInPreparedStatement(JdbcTemplate.java:866) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:629) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
... 83 common frames omitted
作业定义为:
<beans:bean id="cleanCurrentTradesTasklet"
class="com.bank.dept.app.batch.tasklet.CleanCurrentTradesTasklet" scope="step">
</beans:bean>
<batch:job id="tradesLoadJob" xmlns="http://www.springframework.org/schema/batch">
<batch:step id="stepCleanTrades" >
<batch:tasklet ref="cleanCurrentTradesTasklet" allow-start-if-complete="true" />
</batch:step>
</batch:job>
工作class:
public class CleanCurrentTradesTasklet implements Tasklet {
@Autowired
TradesDao tradesDao;
@Override
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1) throws Exception {
tradesDao.deleteCurrentTrades();
return RepeatStatus.FINISHED;
}
}
测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:app-dml-subscriber-top-level-test.xml" })
@ActiveProfiles(profiles={"local","notification-no-ssl","no-stock"})
public class IntegrationExistingMessageTest {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void launchAllSteps() throws Exception {
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
}
}
道 class :
@Repository("tradesDao")
public class TradesDaoImpl implements TradesDao {
private static final String UPSTREAM_SYSTEM = "GCAL";
private static final String DELETE_CURRENT_TRADES = "DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID JOIN T_UPSTREAM_SYSTEM S ON S.ID = T.UP_SYS_ID WHERE trunc(T.RECORD_DATE) = trunc(:date) AND S.NAME = :upstream)";
private static final String DELETE_TEST = "DELETE (SELECT F.*, T.* FROM T_TRADE T JOIN T_CASH_FLOW F ON F.TRADE_ID = T.ID WHERE trunc(T.RECORD_DATE) = trunc(:date) AND T.SYS_REF = 'DH1910800009')";
@Override
public void deleteCurrentTrades() {
Date today = new Date(new java.util.Date().getTime());
Map<String, Object> params = new HashMap<>(2);
params.put("date", today);
params.put("upstream", UPSTREAM_SYSTEM);
this.getJdbcTemplate().update(DELETE_CURRENT_TRADES, params);
}
}
我的目标是从 T_TRADE 和 T_CASH_FLOW tables
中删除数据当我将 deleteCurrentTrades() 更改为以下代码时,我没有出现异常:
@Override
public void deleteCurrentTrades() {
Date today = new Date(new java.util.Date().getTime());
Map<String, Object> params = new HashMap<>(1);
params.put("date", today);
this.getJdbcTemplate().update(DELETE_TEST, params);
}
看来问题出在 T_UPSTREAM_SYSTEM table 上的赠款,如下所示:
+-----------+------------------+-----------+-----------+-------------------+
| Privilege | Grantee | Grantable | Grantor | Object Name |
+-----------+------------------+-----------+-----------+-------------------+
| SELECT | APP_MONITORING | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_CONSULT | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_WAS | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | BATCH_USER | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_FR_USER | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
| SELECT | APP_CONSULT_LVL3 | NO | APP_OWNER | T_UPSTREAM_SYSTEM |
+-----------+------------------+-----------+-----------+-------------------+
使用的用户是BATCH_USER
我的查询有什么问题?
似乎 T_TRADE
和 T_CASH_FLOW
是 BATCH_USER
架构的 table,而 T_UPSTREAM_SYSTEM
是 [=16 的 table =]
如果您已授予(SQL> conn APP_OWNER SQL> grant delete on T_UPSTREAM_SYSTEM to BATCH_USER
)对BATCH_USER
的删除权限,您可以通过:
DELETE APP_OWNER.T_UPSTREAM_SYSTEM SS
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND S.ID = SS.ID );
架构名称 APP_OWNER.
为 T_UPSTREAM_SYSTEM
作为前缀。
编辑: (我忘了你想从其他 table 中删除的点,而不是我上面提到的那个).因此,使用以下单独的删除语句:
DELETE T_TRADE TT
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND T.ID = TT.ID );
DELETE T_CASH_FLOW FF
WHERE EXISTS (SELECT 1
FROM T_TRADE T
JOIN T_CASH_FLOW F
ON F.TRADE_ID = T.ID
JOIN APP_OWNER.T_UPSTREAM_SYSTEM S
ON S.ID = T.UP_SYS_ID
WHERE trunc(T.RECORD_DATE) = trunc(?)
AND S.NAME = ?
AND F.TRADE_ID = FF.TRADE_ID );