... ви казва, че вашият spb_getWord()
генерира стойности, които вече съществуват в SPB_WORD
маса. Трябва да актуализирате функцията, за да проверите дали думата вече съществува, преди да излезете от функцията - ако има, генерирайте отново, докато попадне на такава, която не съществува.
Мисля, че вашият spb_runme()
трябва да прилича на:
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;
Използването на това ще ви позволи да промените word_id
да не поддържа NULL. Когато работите с външни ключове, попълнете таблицата първо с препратките към външния ключ - започнете с родителя и след това се заемете с неговите деца.
Другата промяна, която направих, беше да съхраня spb_getWord()
в променлива (v_word
), защото извикването на функцията многократно означава, че ще получавате различна стойност всеки път.
Последно нещо - премахнах оператора за изтриване. Вече сте съкратили таблицата, там няма нищо за изтриване. Със сигурност нищо не е свързано със стойност на j
.