[英]Stored Procedure Postgres and Java
我正在嘗試從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正在獲得這些響應。
有什么方法可以只從過程中獲得最終答復嗎?
當我用單獨的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)<10 THEN。 如果更新引發異常,quantidadeCaracteres的值將永遠不會變大。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.