Обновление первых 7 символов строки другими 3 символами с использованием SQL выдает «Ошибка 19 — ограничение UNIQUE не удалось: MGOFile.File»

У меня довольно простая БД со столбцом с именем Файл, и мне нужно удалить первые 7 символов каждой строки и заменить новой строкой. Я думал, что отсортировал код, но получаю сообщение об ошибке «Ошибка SQLite3 19 — ошибка ограничения UNIQUE: MGOFile.File».

Мое имя таблицы — MGOFile, а столбец — File. Это простой оператор выбора для первых нескольких строк, левый столбец - это необработанные данные, правый - это то, что мне нужно, чтобы результирующие строки выглядели... Обновление первых 7 символов строки другими 3 символами с использованием SQL выдает «Ошибка 19 — ограничение UNIQUE не удалось: 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%';

Но вот где появляется моя ошибка, это терпит неудачу с ошибкой: Обновление первых 7 символов строки другими 3 символами с использованием SQL выдает «Ошибка 19 — ограничение UNIQUE не удалось: MGOFile.File»

Я уверен, что делаю что-то простое неправильно, но я много гуглил, но все ответы выше моих сил, это самый продвинутый SQL, который я пытался сделать!

Любые идеи о том, как обновить эти строки с помощью простого SQLite?

Это означает, что где-то создается дубликат имени файла (столбец «Файл» имеет уникальное ограничение). Вы можете удалить ограничение или найти дубликаты: select 'T:\'|| substr(File, 8,2000) as File, count(*) from MGOFile group by 'T:\'|| substr(File, 8,2000) having count(*) >1;

JohnHC 30.05.2019 11:10

Спасибо @JohnHC, есть ли простой бит SQL, который может отображать дубликаты? Я могу скопировать в excel и найти их таким образом, но я уверен, что это не стандартная практика.

Benno 30.05.2019 11:15

Попробуйте SELECT File from MGOFile WHERE count() > 1 GROUP BY File;

MikeT 30.05.2019 11:16

@MikeT Я получаю сообщение об ошибке «неправильное использование совокупного подсчета ()».

Benno 30.05.2019 11:19

ой, извините 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 30.05.2019 11:24

@MikeT большое спасибо за помощь, вот что самое смешное, этот код не дает результатов. Может ли эта ошибка означать, что будет возвращено что-то еще, кроме неуникальной строки?

Benno 30.05.2019 11:30

@Benno ты пробовал второй с substr ?

MikeT 30.05.2019 11:31

да, я сделал @MikeT, безрезультатно :/

Benno 30.05.2019 13:40
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
8
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ошибка кажется мне совершенно ясной. Вы меняете имя файла на имя, которое уже есть в таблице.

Вы можете определить дубликаты, запустив:

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, я действительно застрял с этим.

Benno 30.05.2019 13:40
Ответ принят как подходящий

Поскольку проверка дубликатов не обнаруживает проблем. Возможно, получение значений во время проблемы может помочь. У тебя случайно нет триггеров? Иногда они будут распространять ошибку, о которой будет сообщено, что она связана с таблицей, вызвавшей срабатывание триггера.

Поэтому, возможно, рассмотрите возможность добавления таблицы для регистрации таких данных вместе с ТРИГГЕРОМ ПЕРЕД ОБНОВЛЕНИЕМ, чтобы фактически регистрировать информацию во время выполнения. Чтобы остановить откат данных и, таким образом, отменить зарегистрированную информацию, необходимо использовать 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

Это, в случае неудачи, запишет

  • n-е обновление в столбце прилавок
  • значение в столбце File перед изменением в столбце последний_файл_перед.
  • значение, на которое будет обновлен столбец «Файл» в столбцах **lastfile_after*.
  • последний идентификатор строки (сбой) строки в таблице MGOFile (это предполагает, что таблица MGOFile не является таблицей, определенной с помощью WITHOUT ROWID).
    • Если таблица была определена с БЕЗ 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; возвращает: -

  • прилавок

    • 6
  • последний_файл_перед =

    • 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
  • последний файл_после

    • T:\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.x27
  • id_of_the_row

    • 6

В приведенном выше надуманном примере проблема может быть легко определена (хотя поиск дубликатов также обнаружил ту же проблему), поскольку ошибка находится в 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

Benno 03.06.2019 11:09

Обязательно обратите внимание на триггеры, затем используйте SELECT * FROM sqlite_master WHERE type = 'trigger';. Проблема с SQlite Spy, попробуйте альтернативу, например, DB Browser для SQLite, Navicat. Когда это не удалось, используя вышеприведенное с триггером и дополнительной таблицей. Вы использовали SELECT * FROM lastupdated;? Вы пытались использовать substr(File,8) (т.е. не усекать до 2000)?

MikeT 03.06.2019 22:32

Другие вопросы по теме

Похожие вопросы

Обновить таблицу столбцов со значением столбца из таблицы b, если она содержит подстроку из другого столбца из таблицы b
У меня есть хранимая процедура, и я сделал ее с помощью UNION; как я могу подсчитать общее количество строк?
Android - Комната, как добавить ссылку на внешний ключ для переноса данных
Как создать текущую последовательность в Oracle на основе значений столбца отчета
Обновление значений для всех строк на основе уникального идентификатора — Oracle
Таблица событий запросов BigQuery
Как вставить массив объектов JSON в PostgreSQL как отдельные элементы
Проверьте, имеет ли строка определенное окончание, сотрите это окончание, затем запишите эти строки в соответствии с двумя другими условиями
Учитывая увеличивающиеся значения идентификатора и созданную дату, создайте оператор SQL, чтобы определить, не совпадают ли какие-либо даты с идентификатором в оракуле
Различные строки для результатов при использовании оператора case SQL для одного и того же значения