У меня довольно простая БД со столбцом с именем Файл, и мне нужно удалить первые 7 символов каждой строки и заменить новой строкой. Я думал, что отсортировал код, но получаю сообщение об ошибке «Ошибка SQLite3 19 — ошибка ограничения UNIQUE: MGOFile.File».
Мое имя таблицы — MGOFile, а столбец — File. Это простой оператор выбора для первых нескольких строк, левый столбец - это необработанные данные, правый - это то, что мне нужно, чтобы результирующие строки выглядели...
Я запрашиваю свою таблицу, используя это:
'''sql
SELECT
File,
'T:\'|| substr(File, 8,2000) as File
FROM
MGOFile
WHERE
file like 'M:\_TV%';
'''
Затем я попытался обновить, используя это:
UPDATE MGOFile
SET File = 'T:\' || substr(File, 8, 2000)
WHERE File like 'M:\_TV%';
Но вот где появляется моя ошибка, это терпит неудачу с ошибкой:
Я уверен, что делаю что-то простое неправильно, но я много гуглил, но все ответы выше моих сил, это самый продвинутый SQL, который я пытался сделать!
Любые идеи о том, как обновить эти строки с помощью простого SQLite?
Спасибо @JohnHC, есть ли простой бит SQL, который может отображать дубликаты? Я могу скопировать в excel и найти их таким образом, но я уверен, что это не стандартная практика.
Попробуйте SELECT File from MGOFile WHERE count() > 1 GROUP BY File;
@MikeT Я получаю сообщение об ошибке «неправильное использование совокупного подсчета ()».
ой, извините SELECT File from MGOFile GROUP BY File HAVING count() > 1;
Однако, если дубликат вызван усечением из-за substr(File,8,2000), то вышеуказанное не обнаружит его. Тогда вы можете попробовать SELECT File from MGOFile GROUP BY substr(File,8,2000) HAVING count() > 1;
@MikeT большое спасибо за помощь, вот что самое смешное, этот код не дает результатов. Может ли эта ошибка означать, что будет возвращено что-то еще, кроме неуникальной строки?
@Benno ты пробовал второй с substr ?
да, я сделал @MikeT, безрезультатно :/
Ошибка кажется мне совершенно ясной. Вы меняете имя файла на имя, которое уже есть в таблице.
Вы можете определить дубликаты, запустив:
SELECT f.*
FROM MGOFile f
WHERE EXISTS (SELECT 1
FROM MGOFile f2
WHERE f2.File = 'T:\'|| substr(File, 8,2000)
) AND
f.file LIKE 'M:\_TV%';
Я не знаю, что вы хотите сделать с дубликатом.
Вот где я смущен, этот код не возвращает никаких результатов, заставляя меня думать, что это не дубликат PK, я действительно застрял с этим.
Поскольку проверка дубликатов не обнаруживает проблем. Возможно, получение значений во время проблемы может помочь. У тебя случайно нет триггеров? Иногда они будут распространять ошибку, о которой будет сообщено, что она связана с таблицей, вызвавшей срабатывание триггера.
Поэтому, возможно, рассмотрите возможность добавления таблицы для регистрации таких данных вместе с ТРИГГЕРОМ ПЕРЕД ОБНОВЛЕНИЕМ, чтобы фактически регистрировать информацию во время выполнения. Чтобы остановить откат данных и, таким образом, отменить зарегистрированную информацию, необходимо использовать OR FAIL.
Важно, так как обновления не будут откатываться, обновления будут применены. Предполагается, что вышеизложенное используется в тестовой базе данных.
-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
BEFORE UPDATE ON MGOFile
BEGIN
UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
END
;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
SET File = 'T:\' || substr(File, 8, 2000)
WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail but should be run after the fail
Это, в случае неудачи, запишет
WITHOUT ROWID
).
, id_of_the_row = 0;
. Тогда значение будет бессмысленным.-- Solely for testing the code below
DROP TABLE IF EXISTS MGOFile;
CREATE TABLE IF NOT EXISTS MGOFile (File TEXT PRIMARY KEY);
-- Some testing data
INSERT INTO MGOFile VALUES
('M:\_TV/9-1-1.so2e09.web.x264-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x265-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x277-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x278-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x279-tbs[eztv].mkv'),
('M:\_TV/9-1-1.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x266-tbs[eztv].mkv.so2e09.web.x280-tbs[eztv].mkv')
;
SELECT substr(File,170,8) FROM MGOFile GROUP BY Substr(File,8,170) HAVING count() > 1;
-- The code
DROP TABLE IF EXISTS lastupdated;
-- Create the logging table
CREATE TABLE IF NOT EXISTS lastupdated (counter, lastfile_before, lastfile_after, id_of_the_row);
-- Initialise it so it's plain to see if nothing has been done
INSERT INTO lastupdated VALUES(0,'nothing','nothing',0);
-- Add the Trigger to record the debugging information BEFORE the update
CREATE TRIGGER IF NOT EXISTS monitorupdateprogress
BEFORE UPDATE ON MGOFile
BEGIN
UPDATE lastupdated SET counter = counter +1, lastfile_before = old.File, lastfile_after = new.File, id_of_the_row = old.rowid;
END
;
SELECT * FROM MGOFile;
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK
SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint
WHERE File like 'M:\_TV%';
SELECT * FROM lastupdated; -- will not run if there is a fail
Когда вышеописанное запускается, появляется сообщение: -
UPDATE OR FAIL MGOFile -- OR FAIL will halt but NOT ROLLBACK SET File = 'T:\' || substr(File, 8, 170) -- <<<<<<<<<<<<<<<<<<<< truncate reduced to force UNIQUE constraint WHERE File like 'M:\_TV%' > UNIQUE constraint failed: MGOFile.File > Time: 0.094s
Бег SELECT * FROM lastupdated;
возвращает: -
прилавок
последний_файл_перед =
последний файл_после
id_of_the_row
В приведенном выше надуманном примере проблема может быть легко определена (хотя поиск дубликатов также обнаружил ту же проблему), поскольку ошибка находится в 6-й строке и в строке, которая содержит mkv.so2e09.web.x278-tbs[eztv]
, но была усечена обновлением до .mkv.so2e09.web.x27
, следовательно, это ошибка. дубликат 5-й строки, которая имеет .mkv.so2e09.web.x277-tbs[eztv]
, но также была усечена до .mkv.so2e09.web.x27
.
P.S. Вы пробовали использовать только
UPDATE MGOFile
SET File = 'T:\' || substr(File, 8)
WHERE File like 'M:\_TV%';
то есть удаление усечения.
Спасибо @MikeT за подробный ответ. Чтобы сначала ответить на простой вопрос, да, я пробовал ваш код PS ранее, появляется та же ошибка. Я также попробовал ваше полное предложение, и снова мне была представлена та же ошибка ... Тупик ... Я не верю, что этот файл .db имеет какие-либо триггеры, но кажется, что программное обеспечение, которое я использую «SQLite Spy», не может быть показать мне все? В общем, я не знаю, как двигаться дальше... imgur.com/73wHsR2
Обязательно обратите внимание на триггеры, затем используйте SELECT * FROM sqlite_master WHERE type = 'trigger';
. Проблема с SQlite Spy, попробуйте альтернативу, например, DB Browser для SQLite, Navicat. Когда это не удалось, используя вышеприведенное с триггером и дополнительной таблицей. Вы использовали SELECT * FROM lastupdated;
? Вы пытались использовать substr(File,8)
(т.е. не усекать до 2000)?
Это означает, что где-то создается дубликат имени файла (столбец «Файл» имеет уникальное ограничение). Вы можете удалить ограничение или найти дубликаты:
select 'T:\'|| substr(File, 8,2000) as File, count(*) from MGOFile group by 'T:\'|| substr(File, 8,2000) having count(*) >1;