GARANTIR DESCONTO

Fórum problemas de conversão de string #50464

12/04/2005

0

Bom dia, pessoal.

Bom, criei a seguinte procedure :
CREATE PROCEDURE SP_BUSCAINSERIRCELESC (
  PORTADOR INTEGER
) RETURNS (
  PARCELA DOUBLE PRECISION,
  SUFIXO INTEGER,
  DATAEMISS TIMESTAMP,
  DATAVECTO TIMESTAMP,
  CODCLI CHAR(7),
  DIGCLI CHAR(2),
  NUDOC INTEGER,
  TPDOC CHAR(1)
) AS 
 declare variable clicelesc char(7);
 declare variable digcelesc char(2);
begin
  for select fatura.valor, cast(fatura.sufixo as integer), fatura.dt_emissao,
         fatura.dt_vencimento, cliente.nucodextra, cliente.nudigcodextra,
         fatura.num_nota, fatura.tipo_fatura
  from fatura inner join cliente
  on fatura.id_cliente = cliente.id_cliente
  and fatura.nuportador = :portador
  and fatura.num_nota not in 
  (select nudocumento 
   from itemenviocelesc item
   where item.nudocumento = fatura.num_nota
   and item.nusufixo = cast(fatura.sufixo as integer)) 
  into :parcela, :sufixo, :dataemiss, :datavecto, :clicelesc, :digcelesc, :nudoc, :tpdoc do
  begin
  if (:clicelesc is null) then
    codcli = ´0000000´;
  if (:digcelesc is null) then
    digcli = ´00´;
  end
suspend;
end


Mas ao executa-la recebo o seguinte erro:
Invalid modify request.
Conversion error from string ´´ ´´.


Os campos string envolvidos são cliente.nucodextra, cliente.nudigcodextra e fatura.sufixo. Já fiz um select prá ver se havia algun(s) registro com sufixo nulo ou vazio, mas o select não retornou registo nenhum.

Alguém pode me ajudar...?

Muito obrigado e desculpe o incômodo


Schmidt

Schmidt

Responder

Posts

12/04/2005

Afarias

Acho q o problema é q vc está usando CHAR, um char(4) vazio (não nulo, vazio) por exemplo contém 4 ´espaços´ pois os char sempre contem q quantidade de caracteres definidos.

Tente usando VARCHAR


T+


Responder

Gostei + 0

12/04/2005

Schmidt

Caro afarias!

Rapaz! Tu é bem atuante aqui no fórum, hein!

Seguinte: segui sua dica (aliás, muito obrigado pela mesma) mas acontece que como sou meio ´novato´ nessa história de procedures e selects, essa procedure ´pendurou´ o IBConsole. Você poderia me dar umas dicas de otimização? Estou utilizando o Interbase 6.0.

Muito Obrigado...

________________
Marcelo Schmidt


Responder

Gostei + 0

12/04/2005

Afarias

Consultas com IN (select ... ) geralmente sofrem se o sub-select retorna muitos registros. Se IN pode ser ruim, NOT IN é péssimo!!!

Outra coisa, filtros de registros como

and fatura.nuportador = :portador
and fatura.num_nota not in

deveriam estar no WHERE e não no JOIN (geralmente é mais eficiente -- nem sempre é verdade, além de ser mais fácil ler o SQL)

As vezes é possível colocar a consulta de outra forma para q fique mais eficiente, estude seu modelo de dados.

E procure sempre avaliar o plano de execução (PLAN) da consulta informado pelo IBConsole.


T+


Responder

Gostei + 0

12/04/2005

Schmidt

Obrigado, cara! Valeu mesmo!

Alterei os filtros :portador e fatura.id_cliente... coloquei no where, como você recomendou. E retirei o NOT IN e substitui por NOT EXISTS. Beleza! Não ´pendurou´ mais o IBConsole e me rotornou 7558 registros, mas ainda leva um tempo de 2:20 min prá executar.
A procedure ficou assim:
CREATE PROCEDURE SP_BUSCAINSERIRCELESC (
  PORTADOR INTEGER
) RETURNS (
  PARCELA DOUBLE PRECISION,
  SUFIXO INTEGER,
  DATAEMISS TIMESTAMP,
  DATAVECTO TIMESTAMP,
  CODCLI VARCHAR(7),
  DIGCLI VARCHAR(2),
  NUDOC INTEGER,
  TPDOC CHAR(1)
) AS  
begin
  for select fatura.valor, cast(fatura.sufixo as integer), fatura.dt_emissao,
         fatura.dt_vencimento, cliente.nucodextra, cliente.nudigcodextra,
         fatura.num_nota, fatura.tipo_fatura
  from fatura inner join cliente
  on fatura.id_cliente = cliente.id_cliente
  where fatura.nuportador = :portador
  and not exists 
  (select nudocumento 
   from itemenviocelesc item
   where item.nudocumento = fatura.num_nota
   and item.tpdocumento = fatura.tipo_fatura
   and item.nusufixo = cast(fatura.sufixo as integer)) 
  into :parcela, :sufixo, :dataemiss, :datavecto, :codcli, :digcli, :nudoc, :tpdoc do
suspend;
end


Por enquanto atende às expectativas, mas vou estudar uma maneira de reprojetar o banco (não fui eu quem o projetou).

Valeu, Cara!

Sucesso prá você.

________________
Marcelo Schmidt


Responder

Gostei + 0

12/04/2005

Afarias

Ok...

qualquer coisa, poste sempre o PLAN da query (além da própria) para o pessoal poder ajudar.


T+


Responder

Gostei + 0

12/04/2005

Emerson Nascimento

CREATE PROCEDURE SP_BUSCAINSERIRCELESC ( 
  PORTADOR INTEGER 
) RETURNS ( 
  PARCELA DOUBLE PRECISION, 
  SUFIXO INTEGER, 
  DATAEMISS TIMESTAMP, 
  DATAVECTO TIMESTAMP, 
  CODCLI VARCHAR(7), 
  DIGCLI VARCHAR(2), 
  NUDOC INTEGER, 
  TPDOC CHAR(1) 
) AS  
begin 
  for select fatura.valor, cast(fatura.sufixo as integer), fatura.dt_emissao,
         fatura.dt_vencimento, cliente.nucodextra, cliente.nudigcodextra,
         fatura.num_nota, fatura.tipo_fatura
      from fatura
      inner join cliente on fatura.id_cliente = cliente.id_cliente
      where fatura.nuportador = :portador
      and not exists (select nudocumento
                      from itemenviocelesc item
                      where item.nudocumento = fatura.num_nota
                        and item.tpdocumento = fatura.tipo_fatura
                        and item.nusufixo = cast(fatura.sufixo as integer))
  into :parcela, :sufixo, :dataemiss, :datavecto, :codcli, :digcli, :nudoc, :tpdoc do
  suspend;
end


para melhorar a performance da sua consulta, analise o plano utilizado. geralmente são necessários alguns índices no banco para aumentar a performance das consultas.
no seu caso eu recomendaria criar dois índices (se já não houver):
1 para a tabela fatura, indexado pelo campo nuportador + id_cliente e
1 para a tabela itemenviocelesc, indexado pelos campos nudocumento + tpdocumento + nusufixo.

geralmente você precisa de índices para os campos envolvidos em relacionamentos (join) e para os campos envolvidos em condições de consulta (where)


Responder

Gostei + 0

12/04/2005

Schmidt

UUUUhhh galo!

Emerson e afarias, muitíssimo obrigado.

Criados os índices (no SQLExplorer) como o nosso amigo Emerson recomendou:
create ascending index idx_itemclsc on itemenviocelesc (nudocumento, tpdocumento, nusufixo)
---
create ascending index idx_faturaclsc on fatura (nuportador, id_cliente)
---


E seguindo recomendações do grande afarias temos um tempo de 3 (TRÊS) S E G U N D O S, com este PLAN:
PLAN (ITEM INDEX (IDX_ITEMCLSC))JOIN (FATURA INDEX (IDX_FATURACLSC),CLIENTE INDEX (RDB$PRIMARY12))


Rapaz! Vocês são demais.

Muito obrigado mesmo.

PS: só a titulo de comentário, antes de eu inventar de fazer este select por uma procedure, o pessoal aqui da empresa utilizava [i:f88faafb15]select[/i:f88faafb15] puro mesmo, e a consulta demorava uns 20 MINUTOS.

_________________
Marcelo Schmidt


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar