我有一个相当简单的DB,其列名为File,我需要删除每行的前7个字符,并替换为新的字符串。我以为我对代码进行了排序,但是却出现错误“ SQLite3错误19-唯一约束失败: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更新这些字符串的任何想法?

最佳答案

由于检查重复项似乎无法检测到问题。在问题发生时获取价值也许会有所帮助。您是否有机会触发?这些有时会传播一个错误,该错误将被报告为与触发触发器的表有关。

因此,也许可以考虑添加一个表来记录此类数据,并添加一个“更新前触发器”以在运行时实际记录信息。要停止回滚数据并因此撤消已记录的信息,则需要使用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次更新
在lastfile_before列中更改之前的File列中的值。
“ lastfile_after *”列中“文件”列将更新为的值。
MGOFile表中行的最后一个rowid(失败)(这确实假定MGOFile表不是使用WITHOUT ROWID定义的表)。


如果表是用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;返回:-


计数器


6

lastfile_before =


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

lastfile_after


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

附言您是否尝试过使用

UPDATE MGOFile
SET File = 'T:\' || substr(File, 8)
WHERE File like 'M:\_TV%';


即删除截断。

关于sql - 使用SQL将字符串的前7个字符更新为另外3个字符,将引发“错误19-UNIQUE约束失败:MGOFile.File。”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56374968/

10-12 22:36