简体   繁体   中英

Stored Procedure Postgres and Java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM