簡體   English   中英

存儲過程Postgres和Java

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM