Fórum problemas de conversão de string #50464
12/04/2005
0
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
Curtir tópico
+ 0Posts
12/04/2005
Afarias
Tente usando VARCHAR
T+
Gostei + 0
12/04/2005
Schmidt
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
Gostei + 0
12/04/2005
Afarias
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+
Gostei + 0
12/04/2005
Schmidt
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
Gostei + 0
12/04/2005
Afarias
qualquer coisa, poste sempre o PLAN da query (além da própria) para o pessoal poder ajudar.
T+
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)
Gostei + 0
12/04/2005
Schmidt
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
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)