PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Warum schlägt dieser Code in PostgreSQL fehl und wie kann er behoben werden (Workaround)? Ist es ein Postgres SQL-Engine-Fehler?

... sagt Ihnen, dass Ihr spb_getWord() generiert Werte, die bereits in SPB_WORD vorhanden sind Tisch. Sie müssen die Funktion aktualisieren, um zu überprüfen, ob das Wort bereits existiert, bevor Sie die Funktion verlassen. Wenn dies der Fall ist, generieren Sie es neu, bis es auf eines trifft, das nicht existiert.

Ich denke, Ihr spb_runme() muss ähneln:

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;

Wenn Sie dies verwenden, können Sie die word_id ändern um NULLen nicht zu unterstützen. Wenn Sie mit Fremdschlüsseln arbeiten, füllen Sie die Tabelle zuerst mit den Fremdschlüsselreferenzen - Beginnen Sie mit dem Elternteil und packen Sie dann seine Kinder an.

Die andere Änderung, die ich vorgenommen habe, war das Speichern von spb_getWord() in einer Variablen (v_word ), da ein mehrmaliges Aufrufen der Funktion bedeutet, dass Sie jedes Mal einen anderen Wert erhalten würden.

Letzte Sache - ich habe die Löschanweisung entfernt. Sie haben die Tabelle bereits abgeschnitten, es gibt nichts zu löschen. Sicherlich nichts mit einem Wert von j verbunden .