I'm trying to run a stored procedure in Postgres from my java application, this is the procedure:
CREATE OR REPLACE FUNCTION geraCodigo() RETURNS integer AS $a$
DECLARE
codigo varchar;
codigoNovo varchar;
maximoRegistros integer;
contador integer := 1;
quantidadeCaracteres integer;
BEGIN
maximoRegistros := (SELECT count(id) FROM gisTemp);
RAISE NOTICE 'Contador % ',contador;
RAISE NOTICE 'maximoRegistros % ',maximoRegistros;
LOOP
RAISE NOTICE 'Contador % ',contador;
IF (SELECT tipoTensao FROM gisTemp WHERE id = contador) = 'MT' THEN
/*CHECA DIGITO 5 DO codConsumidor E PROCESSA DE ACORDO COM RESULTADO */
IF (SELECT substring(codConsumidor from 4 for 1) FROM gisTemp WHERE id = contador) = '1' THEN
quantidadeCaracteres = (SELECT char_length((SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)));
IF (quantidadeCaracteres) < 10 THEN
LOOP
BEGIN
UPDATE gisTemp SET idsap = concat('0',(SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)) WHERE id = contador;
quantidadeCaracteres := quantidadeCaracteres + 1;
EXCEPTION WHEN invalid_text_representation THEN
------ NÃO FAZ NADA
END;
EXIT WHEN quantidadeCaracteres >= 10;
END LOOP;
ELSE
UPDATE gisTemp SET idsap = (SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador) WHERE id = contador;
END IF;
ELSIF (SELECT substring(codConsumidor from 4 for 1) FROM gisTemp WHERE id = contador) = '2' THEN
quantidadeCaracteres = (SELECT char_length((SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)));
IF (quantidadeCaracteres) < 10 THEN
LOOP
BEGIN
UPDATE gisTemp SET idsap = concat('0',(SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)) WHERE id = contador;
quantidadeCaracteres := quantidadeCaracteres + 1;
EXCEPTION WHEN invalid_text_representation THEN
------ NÃO FAZ NADA
END;
EXIT WHEN quantidadeCaracteres >= 10;
END LOOP;
ELSE
UPDATE gisTemp SET idsap = (SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador) WHERE id = contador;
END IF;
ELSIF (SELECT substring(codConsumidor from 4 for 1) FROM gisTemp WHERE id = contador) = '0' THEN
UPDATE gisTemp
SET idsap = concat((SELECT substring(codConsumidor from 0 for 4) FROM gisTemp WHERE id = contador),(SELECT substring(codConsumidor from 6 for 10) FROM gisTemp WHERE id = contador))
WHERE id = contador;
END IF;
ELSIF (SELECT tipoTensao FROM gisTemp WHERE id = contador) = 'BT' THEN
/*CHECA codConsumidor, SE > 18900 PEGA SÓ NÚMEROS*/
BEGIN
IF (SELECT CAST((SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador) AS integer)) > 18900 THEN
/*CHECA O TAMANHO DO IDSAP*/
quantidadeCaracteres = (SELECT char_length((SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)));
IF (quantidadeCaracteres) < 10 THEN
/*LOOP PARA ADICIONAR ZEROS A ESQUERDA*/
LOOP
BEGIN
UPDATE gisTemp SET idsap = concat('0',(SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador)) WHERE id = contador;
quantidadeCaracteres := quantidadeCaracteres + 1;
EXCEPTION WHEN invalid_text_representation THEN
------ NÃO FAZ NADA
END;
EXIT WHEN quantidadeCaracteres >= 10;
END LOOP;
ELSE
UPDATE gisTemp SET idsap = (SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador) WHERE id = contador;
END IF;
/*CHECA codConsumidor, SE <= 18900 PEGA BTE E NÚMEROS*/
ELSIF (SELECT CAST((SELECT substring(codConsumidor from 4 for 10) FROM gisTemp WHERE id = contador) AS integer)) <= 18900 THEN
UPDATE gisTemp SET idsap = concat((SELECT substring(codConsumidor from 0 for 4) FROM gisTemp WHERE id = contador),(SELECT substring(codConsumidor from 6 for 10) FROM gisTemp WHERE id = contador)) WHERE id = contador;
END IF;
EXCEPTION WHEN invalid_text_representation THEN
------ NÃO FAZ NADA
END;
END IF;
contador := contador+1;
EXIT WHEN contador >= maximoRegistros;
END LOOP;
RETURN 1;
END; $a$ LANGUAGE plpgsql;
When I run this in java, I get this error : java.lang.OutOfMemoryError: GC overhead limit exceeded
public boolean processaGISSAP() {
CallableStatement cstmt = null;
try {
String sql = "{call geracodigo()}";
cstmt = con.prepareCall(sql);
cstmt.execute(sql);
} catch (SQLException ex) {
Logger.getLogger(CircuitDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
I think its because in my procedure theres updates and selects, and the java is getting these responses.
Is there any way to get just the final response from a procedure?
When I create those kind of nested function calls with separate BEGIN ... EXCEPTION .. END sections, I make use of different functions. That makes the code at least easier to maintain and read (and debug) in my opinion.
Generally speaking: you have a loop with a test at the end of the code. It is a method, but there is always one problem: what if it does not reach the test or the lines of code that change the values that are tested? Then will it loop forever and will you get the problems you describe. In your code you have several exceptionhandlers. You do nothing at that point. But what if one of those inner loops throw an exception? The value is not updated and the test will not perform well.
With this kind of loop I will always build a security test to prevent it from running forever like this:
cntLoopMax integer:=10
cntLoop integer:=0;
LOOP
BEGIN
...
EXCEPTION
cntLoop := cntLoop + 1;
END
if cntLoop >= cntLoopMax then
raise notice 'exit because of cntLoop exceeds cntLoopMax';
EXIT cntLoop>=cntLoopMax;
end if;
EXIT ...
END LOOP
In your code I see one loop at least that might cause this problem. It is the first loop which starts with: IF (quantidadeCaracteres) < 10 THEN . If the update throws an exception will the value of quantidadeCaracteres never become bigger.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.