简体   繁体   English

存储过程Postgres和Java

[英]Stored Procedure Postgres and Java

I'm trying to run a stored procedure in Postgres from my java application, this is the procedure: 我正在尝试从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;

When I run this in java, I get this error : java.lang.OutOfMemoryError: GC overhead limit exceeded 当我在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;
}

I think its because in my procedure theres updates and selects, and the java is getting these responses. 我认为这是因为在我的过程中有更新和选择,而Java正在获得这些响应。

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. 当我用单独的BEGIN ... EXCEPTION .. END部分创建此类嵌套函数调用时,我使用了不同的函数。 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(quantidadeCaracteres)<10 THEN。 If the update throws an exception will the value of quantidadeCaracteres never become bigger. 如果更新引发异常,quantidadeCaracteres的值将永远不会变大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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