Повторите команду, пока истина или х раз (эквивалент цикла while / for) - PullRequest
0 голосов
/ 28 мая 2019

Я хотел бы повторить эту команду столько раз, сколько еще sometext в поле note (в нескольких строках таблицы itemNotes может быть один или несколько sometext в поле note):

UPDATE itemNotes  
SET 
  note = SUBSTR(note, 0, INSTR(LOWER(note), 'sometext')) || 'abc' || SUBSTR(note, INSTR(LOWER(note), 'sometext')+sometext_len)
WHERE 
  INSTR(LOWER(note), 'sometext') >= 0;

Таким образом, протокод будет выглядеть так:

While (SELECT * FROM itemNotes  WHERE note like "%sometext%") >1

    UPDATE itemNotes  
    SET 
      note = SUBSTR(note, 0, INSTR(LOWER(note), 'sometext')) || 'abc' || SUBSTR(note, INSTR(LOWER(note), 'sometext')+sometext_len)
    WHERE 
      INSTR(LOWER(note), 'sometext') >= 0;
END

Но, очевидно, Sqlite3 не поддерживает цикл while или for.Их можно эмулировать с чем-то вроде this , но у меня возникают трудности при интеграции того, что я хочу, с этим запросом:

    WITH b(x,y) AS 
    (
        SELECT 1,2 
        UNION ALL 
        SELECT x+ 1, y + 1 

    FROM b 
    WHERE x < 20
) SELECT * FROM b;

Есть идеи, как это сделать?

PS:Я не использую replace, потому что хочу заменить все комбинации падежей sometext (например, sometext, SOMEtext, SOmeText ...) на этот вопрос


Текущий ввод и желаемый вывод:

Для одной строки поле заметки может выглядеть так (и многие строки в таблице itemNotes могут выглядеть так):

There is SOmetext and also somETExt and more SOMETEXT and even more sometext

Запрос должен вывести:

There is abc and also abc and more abc and even more abc

Я делаю это на zotero.sqlite, который создается этим файлом(строка 85).Таблица создана по этому запросу

CREATE TABLE itemNotes (
    itemID INTEGER PRIMARY KEY,
    parentItemID INT,
    note TEXT,
    title TEXT,
    FOREIGN KEY (itemID) REFERENCES items(itemID) ON DELETE CASCADE,
    FOREIGN KEY (parentItemID) REFERENCES items(itemID) ON DELETE CASCADE
);

Ответы [ 2 ]

1 голос
/ 28 мая 2019

Как рекомендовал Стефан в своем последнем комментарии, я использовал Python для этого.

Вот мой код:

import sqlite3
import re
keyword = "sometext"
replacement = "abc"

db = sqlite3.connect(path_to_sqlite)
cursor = db.cursor()

cursor.execute(f'SELECT * FROM itemNotes  WHERE note like "%{keyword}%"')

for row in cursor.fetchall():
    row_regex = re.compile(re.escape(keyword), re.IGNORECASE)
    row_regex_replaced = row_regex.sub(replacement, row[2])

    rowID = row[0]
    sql = "REPLACE INTO itemNotes (itemID,note) VALUES (?,?)"
    data = (rowID, row_regex_replaced)
    cursor.execute(sql, data)
    db.commit()
1 голос
/ 28 мая 2019

Вы просто получили свой ответ в своем запросе:

UPDATE itemNotes  
SET 
  note = SUBSTR(note, 0, INSTR(LOWER(note), 'sometext')) || 'abc' || SUBSTR(note, INSTR(LOWER(note), 'sometext')+sometext_len)
WHERE 
  note LIKE "%sometext%";

Он обновит все строки, содержащие sometext в поле note

ОБНОВЛЕНИЕ

Если вы хотите обновить поле, которое имеет несколько вхождений в разных случаях, и сохранить оставшуюся часть текста, самое простое решение imo - это использовать regex, и для этого вам нужно расширение

UPDATE itemNotes  
SET 
  note = regex_replace('\bsometext\b',note,'abc')
WHERE 
  note LIKE "%sometext%";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...