Insufficient privileges when deleting

l0r3nz4cc10 :

I have s spring-batch application.

The tests fail somehow with the following error :

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$2.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$1.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$1.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$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$1.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$000(ParentRunner.java:53) [junit-4.11.jar:na]
at org.junit.runners.ParentRunner$2.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$2.doInPreparedStatement(JdbcTemplate.java:873) ~[spring-jdbc-4.2.2.RELEASE.jar:4.2.2.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$2.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

The job is defined by :

<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>

The 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;
    }
}

The test 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());
    }
}

The dao 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);
    }
}

My goal here is to delete data from T_TRADE and T_CASH_FLOW tables

When I change deleteCurrentTrades() to the code below, I don't have the exception :

@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);
}

It seems the problem lies with the grants on the T_UPSTREAM_SYSTEM table, which are below :

+-----------+------------------+-----------+-----------+-------------------+
| 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 |
+-----------+------------------+-----------+-----------+-------------------+

The user used is BATCH_USER

What is wrong with my query ?

Barbaros Özhan :

It seems T_TRADE and T_CASH_FLOW are tables of BATCH_USER schema, and T_UPSTREAM_SYSTEM is a table of APP_OWNER

Provided you have granted ( SQL> conn APP_OWNER SQL> grant delete on T_UPSTREAM_SYSTEM to BATCH_USER ) the delete privilege to the BATCH_USER, you can delete the desired records through :

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 );

with schema name APP_OWNER. prefixed for T_UPSTREAM_SYSTEM.

Edit : ( I forgot the point you wanted to to delete from other tables than the one above I mentioned ). So, use the following seperate delete statements :

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 ); 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=104947&siteId=1