Boa Tarde galera,
Poxa eu sempre me bato quando preciso fazer validação entre datas do tipo que uma data não pode sobrepor a outra, ai não sei direito onde posso fazer a validação, eu sempre faço no WHEN-VALIDATE-ITEM e na PRE-INSERT, mas sempre tem furo, resumindo como eu posso fazer uma validação num bloco multi-record onde as datas não podem se sobrepor.
Ex.: digito 01/01/2008 até 15/01/2008 ai se eu digitar 31/12/2007 e tentar entrar com a data 06/01/2008 ele não deve deixar.
Alguém pode dar essa força que eu acho que é do interesse de todos.
Problemas para Validar Datas
-
- Rank: Programador Sênior
- Mensagens: 60
- Registrado em: Ter, 17 Jan 2006 1:45 pm
- Localização: Santa Catarina
Att.:
Alan Juliano Metzger
Programador Oracle
Inside System Informática
Msn/E-mail: alanjuliano@yahoo.com.br
Alan Juliano Metzger
Programador Oracle
Inside System Informática
Msn/E-mail: alanjuliano@yahoo.com.br
-
- Moderador
- Mensagens: 2016
- Registrado em: Qua, 12 Jan 2005 3:25 pm
- Localização: Araraquara - SP
Abraço,
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Brother,
O que a gente costuma fazer, é uma função (pode ser até de banco), onde você passa varrendo as linhas (PK's) e, verifica o período que está digitando, se está em algum intervalo de linhas já existentes.
É isso que deseja fazer?
Caso positivo, vejo se tenho um exemplo aqui e te envio.
O que a gente costuma fazer, é uma função (pode ser até de banco), onde você passa varrendo as linhas (PK's) e, verifica o período que está digitando, se está em algum intervalo de linhas já existentes.
É isso que deseja fazer?
Caso positivo, vejo se tenho um exemplo aqui e te envio.
- Porva
- Rank: DBA Sênior
- Mensagens: 342
- Registrado em: Seg, 29 Jan 2007 7:36 am
- Localização: São Paulo/SP
Rafael S. Nunes
São Paulo/SP
São Paulo/SP
véio, isso é o 'pulo do gato', vê se você consegue entender:
Ex.: um intervalo cadastrado não pode ser sobreposto por outras datas que compreendam esse mesmo intervalo.
obs: pra ficar fácil pra você adapatar pro seu caso aí, atenta para os nomes 'dt_inicial' e 'dt_final' somente, pra não embolar o entendimento devido aos outros campos.
Ex.: um intervalo cadastrado não pode ser sobreposto por outras datas que compreendam esse mesmo intervalo.
SELECT count(*)
INTO vn_count
FROM rhpessarea
WHERE rhpessarea.cent_cd = :b01.cent_cd
AND rhpessarea.area_cd = :b01.area_cd
AND rhpessarea.pess_cd = :b01.pess_cd
------------------ ESSE É A PARTE QUE INTERESSA ------------------
AND rhpessarea.pesa_dt_inicial <= NVL(:b01.pesa_dt_final, rhpessarea.pesa_dt_inicial)
AND NVL(rhpessarea.pesa_dt_final, :b01.pesa_dt_inicial) >= :b01.pesa_dt_inicial
AND rhpessarea.rowid != NVL(:b01.rowid, 0); --talvez isso não seja necessário, se alguém puder esclarecer melhor
-
- Moderador
- Mensagens: 2016
- Registrado em: Qua, 12 Jan 2005 3:25 pm
- Localização: Araraquara - SP
Abraço,
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Brother,
Eu tinha este teste aqui na minha máquina.
No caso, eu passo apenas uma data, e ele valida pra mim, numa determinada tabela, se pode ou não ser utilizada esta data.
É só adaptar, caso queira passar duas datas para validação.
Esse código acima, foi desenvolvido num bloco anônimo, mas, poderia ser uma função do próprio forms ou, de banco mesmo.
Se ajudar, está valendo.
qualquer coisa, manda ai.
Eu tinha este teste aqui na minha máquina.
No caso, eu passo apenas uma data, e ele valida pra mim, numa determinada tabela, se pode ou não ser utilizada esta data.
É só adaptar, caso queira passar duas datas para validação.
CREATE TABLE tb_teste (cod NUMBER, dt_ini DATE, dt_fim date);
INSERT INTO tb_teste VALUES (1,TO_DATE('01-jan-2007'),TO_DATE('15-jan-2007'));
INSERT INTO tb_teste VALUES (2,TO_DATE('01-jun-2007'),TO_DATE('30-jun-2007'));
INSERT INTO tb_teste VALUES (3,TO_DATE('02-jul-2007'),TO_DATE('31-dec-2007'));
COMMIT;
DECLARE
v_valida BOOLEAN;
FUNCTION fun_data_valida (p_data DATE)
RETURN BOOLEAN
IS
CURSOR cur_param
IS
SELECT dt_ini,
dt_fim
FROM tb_teste
ORDER BY cod;
BEGIN
FOR x IN cur_param
LOOP
IF p_data BETWEEN x.dt_ini AND x.dt_fim
THEN
RETURN FALSE;
END IF;
END LOOP;
RETURN TRUE;
END fun_data_valida;
BEGIN
v_valida := fun_data_valida(TO_DATE('31-DEC-2006'));
IF v_valida
THEN
dbms_output.put_line('Data Válida. Este período pode ser utilizado! ');
ELSE
dbms_output.put_line('Data incorreta. Período já utilizado. ');
END IF;
END;
Se ajudar, está valendo.
qualquer coisa, manda ai.
-
- Rank: DBA Pleno
- Mensagens: 232
- Registrado em: Sex, 30 Mar 2007 7:26 pm
- Localização: Londrina - PR
Rafael O. Genaro
Aproveitando a tabela do exemplo do trevisolli, segue a lógica que uso para validar se um período já foi cadastrado (Este seria o modo mais simples, onde as validações reais são realizadas apenas no PRE-INSERET e PRE-UPDATE, já que os dados que se encontram apenas na tela não são comparados entre si durante antes de um post ou commit do form).
* Obs: considerando que nenhuma das datas pode ser nula, e que já foi previamente validado que a data final >= data inicial.
Geralmente coloco este tipo de validação em uma Program Unit, quee chamo tanto no WHEN-VALIDATE-RECORD quando nas triggers PRE-INSERT e PRE-UPDATE.
Se existe = 1, o período já foi cadastrado.
Caso contrário, existe = 0, e o período ainda não foi cadastrado.
Exemplos:
* O novo período commpreende todos os demais registros cadastrados:
* O novo período inicia em um período cadastrado em um registro, e termina em um período cadastrado em outro registro:
* O novo período inicia dentro do período já cadastrado, e termina em uma data posterior a todos os demais períodos cadastrados:
* O novo período inicia em uma data vaga, e termina em uma data vaga, porém existe um registro já cadastrado que se encontra dentro deste período:
* O novo período tem uma data inicial a menor que as demais datas cadastradas, porém se encerra com uma data posterior à data inicial de algum registro:
* Obs: considerando que nenhuma das datas pode ser nula, e que já foi previamente validado que a data final >= data inicial.
Geralmente coloco este tipo de validação em uma Program Unit, quee chamo tanto no WHEN-VALIDATE-RECORD quando nas triggers PRE-INSERT e PRE-UPDATE.
select count(1) existe
from dual
where exists
(
select 1 from tb_teste t
where ( t.dt_ini between to_date(:bloco.dt_ini, 'yyyymmdd') and to_date(:bloco.dt_fim, 'yyyymmdd')
or t.dt_fim between to_date(:bloco.dt_ini, 'yyyymmdd') and to_date(:bloco.dt_fim, 'yyyymmdd')
or to_date(:bloco.dt_ini, 'yyyymmdd') between t.dt_ini and t.dt_fim
or to_date(:bloco.dt_fim, 'yyyymmdd') between t.dt_ini and t.dt_fim
)
and (t.rowid != :bloco.rowid or :bloco.rowid is null) -- Para evitar a comparação com o próprio registro em um update...
);
Caso contrário, existe = 0, e o período ainda não foi cadastrado.
Exemplos:
* O novo período commpreende todos os demais registros cadastrados:
dt_ini = 20010101 e dt_fim = 20091231
dt_ini = 20070114 e dt_fim = 20070714
dt_ini = 20070801 e dt_fim = 29991231
dt_ini = 20070201 e dt_fim = 20070701
dt_ini = 20010101 e dt_fim = 20070701
- Porva
- Rank: DBA Sênior
- Mensagens: 342
- Registrado em: Seg, 29 Jan 2007 7:36 am
- Localização: São Paulo/SP
Rafael S. Nunes
São Paulo/SP
São Paulo/SP
só fazendo uma correção no exemplo que passei:
'ou seja, ele vai retornar o Count (maior que 0) caso o período que você está informando NÃO ESTEJA CADASTRADO, ou seja, esteja disponível.'
na verdade, é o contrário, se retornar o Count > 0 é porquê o perído JÁ ESTÁ cadastrado.
'ou seja, ele vai retornar o Count (maior que 0) caso o período que você está informando NÃO ESTEJA CADASTRADO, ou seja, esteja disponível.'
na verdade, é o contrário, se retornar o Count > 0 é porquê o perído JÁ ESTÁ cadastrado.
-
- Rank: Estagiário Pleno
- Mensagens: 4
- Registrado em: Qua, 29 Jun 2005 11:54 am
- Localização: SP
Aproveitando este tópico. Como devo proceder caso queira validar somente as datas que estão em tela, ou seja, ainda não foram comitadas em banco?
Segue exemplo de rotina que estou tentando montar. Funciona em parte mas ainda está com fuos na validação. Se alguém puder ajudar, fico agradecido.
Segue exemplo de rotina que estou tentando montar. Funciona em parte mas ainda está com fuos na validação. Se alguém puder ajudar, fico agradecido.
PROCEDURE VALIDA_DT_TERMINO_AGRUP IS
v_dt_inicio date;
v_dt_termino date;
v_teste number;
v_existe varchar2(1);
BEGIN
v_dt_inicio := :agrcob_vig.dt_inicio_vigencia;
v_dt_termino := :agrcob_vig.dt_final_vigencia;
FIRST_RECORD;
LOOP
v_existe := 'N';
v_teste := :system.cursor_record;
first_record;
loop
if (v_dt_inicio between :agrcob_vig.dt_inicio_vigencia and :agrcob_vig.dt_final_vigencia )then -- or
--(:agrcob_vig.dt_inicio_vigencia >= v_dt_inicio) then
v_existe := 'S';
elsif v_dt_termino between :agrcob_vig.dt_inicio_vigencia and :agrcob_vig.dt_final_vigencia then
v_existe := 'S';
end if;
if v_teste = 1 then
v_existe := 'N';
end if;
if :system.cursor_record = v_teste then
v_existe := 'N';
end if;
if v_existe ='S' then
mensagem ('Existem datas entre os intervalos.');
raise form_trigger_failure;
end if;
if :system.cursor_record = v_teste then
exit;
end if;
next_record;
end loop;
go_record(v_teste);
if :system.last_record = 'TRUE' then
exit;
end if;
next_record;
END loop;
EXCEPTION
when form_trigger_failure then
raise form_trigger_failure;
WHEN OTHERS THEN
CGTE$OTHER_EXCEPTIONS;
END;
-
- Moderador
- Mensagens: 2016
- Registrado em: Qua, 12 Jan 2005 3:25 pm
- Localização: Araraquara - SP
Abraço,
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP
Brother,
Pra verificação das datas digitadas ainda na tela, que não estão no banco, você pode "simular" essa informação no banco, com o comando:
Só analise o local ideal pra se colocar essa informação/comando (Talvez no teu When-Validate-Record).
Pra verificação das datas digitadas ainda na tela, que não estão no banco, você pode "simular" essa informação no banco, com o comando:
POST;
-
- Informação
-
Quem está online
Usuários navegando neste fórum: Nenhum usuário registrado e 17 visitantes