PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Por que esse código falha no PostgreSQL e como corrigi-lo (contorno)? É falha do mecanismo Postgres SQL?


...está dizendo que seu spb_getWord() está gerando valores que já existem no SPB_WORD tabela. Você precisa atualizar a função para verificar se a palavra já existe antes de sair da função - se existir, gere novamente até atingir uma que não exista.

Acho que seu spb_runme() precisa se parecer com:
create or replace function spb_runme() returns void as $$
DECLARE
  v_word VARCHAR(410);

begin
  perform setval('spb_wordnum_seq', 1, false);
  truncate table spb_word4obj, spb_word, spb_obj_word;

  for j in 0 .. 50000-1 loop

    if j % 100 = 0 then raise notice 'j = %', j; end if;

    for i in 0 .. 20 - 1 loop
      v_word := spb_getWord();
      INSERT INTO spb_word (word) VALUES (v_word);

      INSERT INTO spb_word4obj 
        (word, idx, doc_id, word_id)
        SELECT w.word, i, j, w.id
          FROM SPB_WORD w 
         WHERE w.word = v_word;

    end loop;

    INSERT INTO spb_obj_word (word_id, idx, doc_id) 
    SELECT w4o.word_id, w4o.idx, w4o.doc_id 
      FROM SPB_WORD4OBJ w4o 
     WHERE w40.doc_id = j;

  end loop;
end;

Usar isso permitirá que você altere o word_id para não suportar NULLs. Ao lidar com chaves estrangeiras, preencha a tabela com as referências de chave estrangeira primeiro - comece com o pai e, em seguida, enfrente seus filhos.

A outra mudança que fiz foi armazenar o spb_getWord() em uma variável (v_word ), porque chamar a função várias vezes significa que você obteria um valor diferente a cada vez.

Última coisa - eu removi a instrução delete. Você já truncou a tabela, não há nada lá para excluir. Certamente nada associado a um valor de j .