Assumindo que você queira criar um programa que faça uma transação refletir o novo saldo na tabela CCA, você precisa "incrementar" ou "decrementar" a quantia inserida no campo saldo da tabela existente. Ou seja: inserir se for a primeira vez, ou update se a linha já existir.
Agora como evitar que a tabela CCA fique com saldos inconsistentes... um jeito é revogar privilégios de insert/update/delete (qualquer DML) nas tabela CCA e TRANSACAO, permitindo que apenas a aplicação autorizada a fazer isso seja uma API contendo a transação (insere em Transação e atualiza CCA em conjunto).
Pode ser tentador fazer isso por trigger, mas eu não gosto da ideia de usar trigger para isso, pois oculta a lógica e dificulta muito a manutenção futura, além de ser altamente vulnerável a bugs; o que deixaria sua tabela CCA propensa a ficar inconsistente.
Segue um exemplo de uma maneira de fazer isso por package:
Selecionar tudo
SQL> CREATE TABLE transacao (
2 CPF NUMBER(11) NOT NULL ,
3 NUM_AG NUMBER(3) NOT NULL ,
4 NUM_CONTA NUMBER(6) NOT NULL ,
5 ID_TRANS NUMBER(3) NOT NULL ,
6 TIPO NUMBER(3) NOT NULL,
7 DATA TIMESTAMP(6) NOT NULL ,
8 QUANTIA FLOAT(126));
Table created
SQL> CREATE TABLE CCA (
2 CPF NUMBER(11) NOT NULL ,
3 NUM_AG NUMBER(3) NOT NULL ,
4 NUM_CONTA NUMBER(6) NOT NULL ,
5 SALDO FLOAT(126) NOT NULL);
Table created
SQL> CREATE SEQUENCE SQ_ID_TRANS START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE;
Sequence created
SQL> create or replace package pk_movimenta_conta as
2
3 procedure registra_transacao (p_CPF IN transacao.cpf%type,
4 p_NUM_AG IN transacao.num_ag%type,
5 p_NUM_CONTA IN transacao.num_conta%type,
6 p_TIPO IN transacao.tipo%type,
7 p_DATA IN transacao.data%type,
8 p_QUANTIA IN transacao.quantia%type,
9 p_ID_TRANS OUT transacao.id_trans%type);
10
11 end pk_movimenta_conta;
12 /
Package created
SQL> create or replace package body pk_movimenta_conta as
2
3
4 procedure registra_transacao (p_CPF IN transacao.cpf%type,
5 p_NUM_AG IN transacao.num_ag%type,
6 p_NUM_CONTA IN transacao.num_conta%type,
7 p_TIPO IN transacao.tipo%type,
8 p_DATA IN transacao.data%type,
9 p_QUANTIA IN transacao.quantia%type,
10 p_ID_TRANS OUT transacao.id_trans%type) is
11 begin
12 select sq_id_trans.nextval into p_id_trans from dual;
13 insert into transacao (CPF ,
14 NUM_AG ,
15 NUM_CONTA,
16 ID_TRANS ,
17 TIPO ,
18 DATA ,
19 QUANTIA )
20 values (p_CPF ,
21 p_NUM_AG ,
22 p_NUM_CONTA,
23 p_ID_TRANS ,
24 p_TIPO ,
25 p_DATA ,
26 p_QUANTIA );
27
28 merge into cca c
29 using (select cpf, num_ag, num_conta, quantia
30 from transacao
31 where id_trans = p_id_trans) t
32 on (c.cpf = t.cpf and c.num_ag = t.num_ag and c.num_conta = t.num_conta)
33 when matched then
34 update set c.saldo = c.saldo + p_quantia
35 when not matched then
36 insert (c.cpf, c.num_ag, c.num_conta, c.saldo)
37 values (p_cpf, p_num_ag, p_num_conta, p_quantia);
38 end;
39
40 end pk_movimenta_conta;
41 /
Package body created
SQL> DECLARE
2 v_id_trans NUMBER;
3 BEGIN
4 -- registra transação na primeira conta (insere)
5 pk_movimenta_conta.registra_transacao(p_cpf => 00012345678,
6 p_num_ag => 1,
7 p_num_conta => 9999,
8 p_tipo => 3,
9 p_DATA => trunc(SYSDATE),
10 p_quantia => 1000.00,
11 p_id_trans => v_id_trans);
12 -- registra transação na primeira conta (atualiza)
13 pk_movimenta_conta.registra_transacao(p_cpf => 00012345678,
14 p_num_ag => 1,
15 p_num_conta => 9999,
16 p_tipo => 3,
17 p_DATA => trunc(SYSDATE),
18 p_quantia => 1000.00,
19 p_id_trans => v_id_trans);
20 -- registra transação na segunda conta (insere)
21 pk_movimenta_conta.registra_transacao(p_cpf => 333,
22 p_num_ag => 1,
23 p_num_conta => 9990,
24 p_tipo => 3,
25 p_DATA => trunc(SYSDATE),
26 p_quantia => 5000.00,
27 p_id_trans => v_id_trans);
28 -- registra transação na segunda conta (atualiza)
29 pk_movimenta_conta.registra_transacao(p_cpf => 333,
30 p_num_ag => 1,
31 p_num_conta => 9990,
32 p_tipo => 3,
33 p_DATA => trunc(SYSDATE),
34 p_quantia => 5000.00,
35 p_id_trans => v_id_trans);
36 END;
37 /
PL/SQL procedure successfully completed
SQL> select * from transacao;
CPF NUM_AG NUM_CONTA ID_TRANS TIPO DATA QUANTIA
------------ ------ --------- -------- ---- ------------------------------------------------- --------------------------------------------------------------------------------
12345678 1 9999 1 3 28/06/12 00:00:00,000000 1000
12345678 1 9999 2 3 28/06/12 00:00:00,000000 1000
333 1 9990 3 3 28/06/12 00:00:00,000000 5000
333 1 9990 4 3 28/06/12 00:00:00,000000 5000
SQL> select * from cca;
CPF NUM_AG NUM_CONTA SALDO
------------ ------ --------- --------------------------------------------------------------------------------
12345678 1 9999 2000
333 1 9990 10000
SQL> drop table transacao;
Table dropped
SQL> drop table cca;
Table dropped
SQL> drop sequence sq_id_trans;
Sequence dropped
SQL> drop package pk_movimenta_conta;
Package dropped
SQL>
Lembro que é extremamente importante tirar os grants de insert/update/delete nas tabelas, para impedir outras aplicações e usuários de manipulá-las sem respeitar a lógica da transação.