PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Perché questo codice non riesce in PostgreSQL e come risolverlo (soluzione alternativa)? È un difetto del motore SQL di Postgres?

...ti dice che il tuo spb_getWord() sta generando valori che esistono già in SPB_WORD tavolo. È necessario aggiornare la funzione per verificare se la parola esiste già prima di uscire dalla funzione:in tal caso, rigenerare finché non ne raggiunge una che non lo è.

Penso che il tuo spb_runme() deve assomigliare a:

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;

L'utilizzo di questo ti consentirebbe di modificare il word_id per non supportare NULL. Quando si tratta di chiavi esterne, compilare la tabella a cui fa riferimento prima la chiave esterna - inizia con il genitore e poi affronta i suoi figli.

L'altra modifica che ho apportato è stata quella di memorizzare spb_getWord() in una variabile (v_word ), perché chiamare la funzione più volte significa che otterresti ogni volta un valore diverso.

Ultima cosa:ho rimosso l'istruzione di eliminazione. Hai già troncato la tabella, non c'è niente da eliminare. Certamente nulla associato a un valore di j .