1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

PL/SQL Gerar Row ID

Discussão em 'Programação' iniciada por PMorgado, 11 de Junho de 2007. (Respostas: 3; Visualizações: 1216)

  1. Boas,

    Tenho um script que insere um novo registo numa tabela.
    O campo do row_id é calculado com uma subquery.
    Não posso automatizar este processo pois não me é possivel alterar o tipo de campo row_id que é varchar.

    O problema é que muitas vezes este script é despoletado exactamente ao mesmo tempo mais do que uma vez.
    O que provoca que o resultado da subquery para saber o row_id devolva o mesmo valor para dois ou mais inserts, o que viola a chave e um ou mais registos não são inseridos.

    A query é esta:

    BEGIN
    INSERT INTO CX_EIM_LOG
    (ROW_ID, CREATED_BY, LAST_UPD_BY, EIM_TABLE, H_INICIO,CONCEITO, N_CADEIA)
    VALUES ((SELECT MAX(TO_NUMBER(ROW_ID)) FROM CX_EIM_LOG) + 1, (SELECT ROW_ID FROM S_USER WHERE LOGIN ='&3'), (SELECT ROW_ID FROM S_USER WHERE LOGIN ='&3'), '&1',SYSDATE,'&2',(SELECT MAX(N_CADEIA) FROM CX_EIM_LOG WHERE CONCEITO ='&2')+1);
    END;
    /
    COMMIT;
    QUIT

    alguma sugestão de forma a que esta query não seja executada mais do que uma vez ao mesmo tempo?

    tks
    cpts
    PM
     
  2. selipequenote

    selipequenote Power Member

    Qual é o SGBD? Se puderes usa transacções...
     
  3. Karski

    Karski Power Member

    Não uses esse select com o max, até porque quando tiveres milhares de registos nessa tabela ias estar a fazer um full À mesma cada vez que quisesses inserir lá um novo registo.

    Não sei se o SGBD que estás a usar permite usares sequências, mas se sim crias uma sequência para isso e vais buscar o novo registo à respectiva sequência.

    Se não tiveres essa possibilidade podes sempre criar uma solução mais "martelada" tipo criares uma tabela com 2 colunas. A 1ª coluna é o nome da tua tabela e a 2ª coluna é o próximo registo que vais ter quando inserires algo (do género de uma numeração). Assim quando quiseres um novo registo fazes um select campo for update (assim reservas o registo) e fazes o insert na tua tabela e logo de seguida incrementas a tabela das numerações libertando nesse momento o registo.

    Espero ter ajudado. Com certeza que se pensares um bocado consegues arranjar outras soluções também
     
  4. O SGBD é o ORACLE

    Obrigado pela dica da sequencialização.

    Aproveitando a ideia de usar transacção, posso colocar:

    set transaction isolation level serializable;

    E de seguida o INSERT?
     

Partilhar esta Página