Boa tarde !
A executar uma trigger recebo a mensagem at end of table. Ela se dá em função de um select que numa determinada situação não traz resultado algum. Gostaria de saber se tem como tratar essa mensagem de forma que não impeça a excecução do resto da trigger.
Obrigado.
At end of table
-
- Rank: Analista Júnior
- Mensagens: 73
- Registrado em: Qui, 21 Set 2006 10:13 am
- Localização: sp
- dr_gori
- Moderador
- Mensagens: 5026
- Registrado em: Seg, 03 Mai 2004 3:08 pm
- Localização: Portland, OR USA
- Contato:
Thomas F. G
Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered
Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered
Como assim?
Você faz um select dentro de uma trigger de banco?
Explica melhor o que você está fazendo pra gente entender!!!
Você faz um select dentro de uma trigger de banco?
Explica melhor o que você está fazendo pra gente entender!!!

-
- Rank: Analista Júnior
- Mensagens: 73
- Registrado em: Qui, 21 Set 2006 10:13 am
- Localização: sp
A trigger é a seguinte (a parte em vermelho é que eu estou com problema):
create or replace trigger teste
before insert on TITMMOVCOMPL
for each row
declare
OST TITMMOVCOMPL.OS%type;
TP CHAR;
DTOS DATE ;
I VARCHAR2(15);
preço TPRD.PRECO1%TYPE;
QTDE TITMMOV.QUANTIDADE%TYPE;
CODIGO TPRD.CODIGOPRD%TYPE;
TPMOV TMOV.CODTMV%TYPE;
begin
SELECT CODTMV INTO TPMOV
FROM TMOV
WHERE IDMOV=:NEW.IDMOV;
IF TPMOV='1.1.04' AND :NEW.OS IS NOT NULL THEN
IF :NEW.OS IS NOT NULL THEN
SELECT NR_ORDSERV into OST
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
SELECT TP_MANUT INTO TP
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
SELECT DH_SAIDA INTO DTOS
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
SELECT TPRD.CODIGOPRD INTO CODIGO
FROM TPRD,TITMMOV
WHERE TPRD.IDPRD=TITMMOV.IDPRD
AND TITMMOV.IDMOV=:NEW.IDMOV
AND TITMMOV.NSEQITMMOV=:NEW.NSEQITMMOV;
SELECT CD_PECA INTO I FROM HISTPECA@GUB -------------------- H E R E ! ! !--------------------
WHERE NR_ORDSERV=TO_NUMBER(:NEW.OS,'9999999999') -------------------- H E R E ! ! !--------------------
AND CD_PECA=CODIGO; -------------------- H E R E ! ! !--------------------
IF OST IS NOT NULL AND DTOS IS NOT NULL THEN
RAISE_APPLICATION_ERROR (-20001,'OS Nº '||:NEW.OS||' ESTÁ FECHADA !!!');
ELSIF OST IS NOT NULL THEN
SELECT TPRD.CODIGOPRD, TITMMOV.QUANTIDADE,TPRD.PRECO1 INTO CODIGO, QTDE,preço
FROM TPRD,TITMMOV
WHERE TPRD.IDPRD=TITMMOV.IDPRD
AND TITMMOV.IDMOV=:NEW.IDMOV
AND TITMMOV.NSEQITMMOV=:NEW.NSEQITMMOV;
IF I<>CODIGO THEN
INSERT INTO HISTPECA@GUB (NR_ORDSERV,CD_PECA,QT_PECA,CD_EMPRESA,CD_PECA_CO,
NR_SER,TP_CTRL,CD_EMP_USU,CD_USUARIO,DH_ULT_ATZ,NR_REQ,VL_CUSTO,DT_UTILIZA)
VALUES (:NEW.OS,CODIGO,QTDE,1,'VAZIO','U',TP,1,1,SYSDATE,:NEW.OS,preço,SYSDATE);
ELSE
UPDATE HISTPECA@GUB
SET QT_PECA=(QT_PECA + QTDE),DH_ULT_ATZ=SYSDATE,DT_UTILIZA=SYSDATE
WHERE NR_ORDSERV=TO_NUMBER(:NEW.OS,'9999999999')
AND CD_PECA=CODIGO;
END IF;
ELSIF OST IS NULL AND :NEW.OS IS NOT NULL THEN
RAISE_APPLICATION_ERROR (-20001,'OS INEXISTENTE !!!');
END IF;
END IF;
END IF;
end teste;
-
- Rank: DBA Pleno
- Mensagens: 264
- Registrado em: Dom, 19 Ago 2007 8:18 pm
- Localização: Ribeirão Preto - SP
Lucas de Souza
OCA Developer
Analista de sistemas
OCA Developer
Analista de sistemas
olha cara... eu vo ti falar uma super dica que um amigo meu (OCP Developer) sempre me falava =D
quando você for fazer triggers, packages ou até no forms....
em todo select qui você for fazer, sempre separe eles com BEGIN...EXCEPTION...END desse modo, você pode tratar cada erro de cada select separadamente... ou intao crie uma variavel numérica vn_erro, que a cada passo qui o seu script anda, ele recebe uma valor diferente, e nos exceptions mostre esse valor, para você saber onde está o erro
=D
quando você for fazer triggers, packages ou até no forms....
em todo select qui você for fazer, sempre separe eles com BEGIN...EXCEPTION...END desse modo, você pode tratar cada erro de cada select separadamente... ou intao crie uma variavel numérica vn_erro, que a cada passo qui o seu script anda, ele recebe uma valor diferente, e nos exceptions mostre esse valor, para você saber onde está o erro
=D
-
- Rank: Analista Júnior
- Mensagens: 73
- Registrado em: Qui, 21 Set 2006 10:13 am
- Localização: sp
Lucas, será que você podia exemplificar as duas situações para mim. Sou iniciante. Desde já, obrigado pela atenção.
-
- Rank: DBA Pleno
- Mensagens: 264
- Registrado em: Dom, 19 Ago 2007 8:18 pm
- Localização: Ribeirão Preto - SP
Lucas de Souza
OCA Developer
Analista de sistemas
OCA Developer
Analista de sistemas
então, seria meio assim:
mais ai depende também da sua regra de negocio, as vezes não dá pra você fazer isso em todos os selects, e existem varios outros tipos exeptions, e você pode colocar uma ação NULL em um exception
um outro modo seria assim também... mais ai é mais para rastrear erros...
assim você vai poder saber onde qui aconteceu o erro também....
mais não vai poder trata-lo iguai no primeiro exemplo
create or replace trigger teste
before insert on TITMMOVCOMPL
for each row
DECLARE
OST TITMMOVCOMPL.OS%type;
TP CHAR;
DTOS DATE ;
I VARCHAR2(15);
preço TPRD.PRECO1%TYPE;
QTDE TITMMOV.QUANTIDADE%TYPE;
CODIGO TPRD.CODIGOPRD%TYPE;
TPMOV TMOV.CODTMV%TYPE;
BEGIN
SELECT CODTMV INTO TPMOV
FROM TMOV
WHERE IDMOV=:NEW.IDMOV;
IF TPMOV='1.1.04' AND :NEW.OS IS NOT NULL THEN -- Aqui você já faiz um "IF :NEW.OS IS NOT NULL", não precisa repeti-lo
-- IF :NEW.OS IS NOT NULL THEN
BEGIN
SELECT NR_ORDSERV into OST
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
EXCEPTION
when no_data_found then
RAISE_APPLICATION_ERROR(-20001, 'não encontrado');
when others then
RAISE_APPLICATION_ERROR(-20001, 'erro: '||sqlerrm);
END;
BEGIN
SELECT TP_MANUT INTO TP
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
EXCEPTION
when no_data_found then
RAISE_APPLICATION_ERROR(-20001, 'não encontrado');
when others then
RAISE_APPLICATION_ERROR(-20001, 'erro: '||sqlerrm);
END;
BEGIN
SELECT DH_SAIDA INTO DTOS
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
EXCEPTION
when no_data_found then
RAISE_APPLICATION_ERROR(-20001, 'não encontrado');
when others then
RAISE_APPLICATION_ERROR(-20001, 'erro: '||sqlerrm);
END;
.......
um outro modo seria assim também... mais ai é mais para rastrear erros...
create or replace trigger teste
before insert on TITMMOVCOMPL
for each row
DECLARE
OST TITMMOVCOMPL.OS%type;
TP CHAR;
DTOS DATE ;
I VARCHAR2(15);
preço TPRD.PRECO1%TYPE;
QTDE TITMMOV.QUANTIDADE%TYPE;
CODIGO TPRD.CODIGOPRD%TYPE;
TPMOV TMOV.CODTMV%TYPE;
BEGIN
SELECT CODTMV INTO TPMOV
FROM TMOV
WHERE IDMOV=:NEW.IDMOV;
IF TPMOV='1.1.04' AND :NEW.OS IS NOT NULL THEN -- Aqui você já faiz um "IF :NEW.OS IS NOT NULL", não precisa repeti-lo
-- IF :NEW.OS IS NOT NULL THEN
vn_erro := 0;
SELECT NR_ORDSERV into OST
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
vn_erro := 1;
SELECT TP_MANUT INTO TP
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
vn_erro := 2;
SELECT DH_SAIDA INTO DTOS
FROM HISTMANU@GUB
WHERE NR_ORDSERV=:NEW.OS;
END IF;
EXCEPTION
when others then
RAISE_APPLICATION_ERROR(-20001, '('||vn_erro||')Erro: '||sqlerrm);
end teste;
mais não vai poder trata-lo iguai no primeiro exemplo
-
- Rank: Analista Júnior
- Mensagens: 73
- Registrado em: Qui, 21 Set 2006 10:13 am
- Localização: sp
Boa tarde Lucas, tudo bem ?
Acho que talvez eu não esteja me fazendo entender.
O problema que estou tendo está no select em vermelho. Na maioria das vezes ele não irá retornar valor algum. Em função disso, a execução da trigger é interrompida quando isto ocorre. Queria saber se tem como tratar isso de forma que continue a executar o resto da trigger.....
Muito obrigado pela sua atenção.
Acho que talvez eu não esteja me fazendo entender.
O problema que estou tendo está no select em vermelho. Na maioria das vezes ele não irá retornar valor algum. Em função disso, a execução da trigger é interrompida quando isto ocorre. Queria saber se tem como tratar isso de forma que continue a executar o resto da trigger.....
Muito obrigado pela sua atenção.
-
- Rank: Analista Júnior
- Mensagens: 96
- Registrado em: Qua, 21 Jun 2006 11:33 pm
- Localização: Canoas RS
BEGIN
SELECT CD_PECA INTO I FROM HISTPECA@GUB
WHERE NR_ORDSERV=TO_NUMBER(:NEW.OS,'9999999999')
AND CD_PECA=CODIGO;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
-
- Rank: Analista Júnior
- Mensagens: 96
- Registrado em: Qua, 21 Jun 2006 11:33 pm
- Localização: Canoas RS
Só para avisar, comandos SELECT INTO muitas vezes geram problemas que demoram horas para se descobrir como resolver, por isso vai a dica: use SEMPRE cursores!


-
- Rank: DBA Pleno
- Mensagens: 264
- Registrado em: Dom, 19 Ago 2007 8:18 pm
- Localização: Ribeirão Preto - SP
Lucas de Souza
OCA Developer
Analista de sistemas
OCA Developer
Analista de sistemas
mais usar cursores não piora a performace do comando inteiro ?
até onde eu sei quando você usa um cursor a cada linha do cursor ele faiz um parse a mais no banco, então dependendo do seu select, ele ficaria mais lento que no caso do INTO....
eu uso o cursor quando eu preciso de mais de um valor retornado do select.... mais quando se trata de uma linha apenas é muito mais util o uso do SELECT INTO mesmo....
até onde eu sei quando você usa um cursor a cada linha do cursor ele faiz um parse a mais no banco, então dependendo do seu select, ele ficaria mais lento que no caso do INTO....
eu uso o cursor quando eu preciso de mais de um valor retornado do select.... mais quando se trata de uma linha apenas é muito mais util o uso do SELECT INTO mesmo....
-
- Rank: Analista Júnior
- Mensagens: 73
- Registrado em: Qui, 21 Set 2006 10:13 am
- Localização: sp
Gente, valeu mesmo. Muito obrigado. Vocês me quebraram um galhão.
-
- Rank: Analista Júnior
- Mensagens: 96
- Registrado em: Qua, 21 Jun 2006 11:33 pm
- Localização: Canoas RS
Segundo uma colega dba minha, o oracle internamente cria um cursor para qualquer tipo de consulta então quando tu usa cursores, poupa esse trabalho pro banco e garante controle no teu código, logo, é a melhor prática.mais usar cursores não piora a performace do comando inteiro ?
-
- Informação
-
Quem está online
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante