我正在尝试从我的java应用程序中运行Postgres中的存储过程,这是程序:
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;
当我在java中运行它时,我收到此错误:java.lang.OutOfMemoryError:超出GC开销限制
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;
}
我认为它是因为在我的程序中有更新和选择,而java正在获得这些响应。
有没有办法从程序中获得最终答案?
答案 0 :(得分:0)
当我使用单独的BEGIN ... EXCEPTION .. END部分创建那种嵌套函数调用时,我使用了不同的函数。这使得代码在我看来至少更容易维护和阅读(和调试)。
一般来说:在代码末尾有一个带测试的循环。这是一种方法,但总有一个问题:如果它没有达到测试或改变测试值的代码行怎么办?然后它将永远循环,你会得到你描述的问题。 在您的代码中,您有几个异常处理程序。那时你什么都不做。但是,如果其中一个内部循环抛出异常呢?该值未更新,测试效果不佳。
通过这种循环,我将始终构建一个安全测试,以防止它像这样永远运行:
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
在您的代码中,我看到至少一个循环可能会导致此问题。这是第一个以下列开头的循环: IF(quantidadeCaracteres)&lt; 10那么 。如果更新抛出异常,则quantdadeCaracteres的值永远不会变大。