【问题标题】:SQLite UPDATE statement is not working inside AFTER INSERT Trigger (Android, Room)SQLite UPDATE 语句在 AFTER INSERT 触发器(Android,Room)中不起作用
【发布时间】:2019-11-22 12:52:23
【问题描述】:

我的 SQL:

这不起作用:我希望这个触发器起作用。

CREATE TRIGGER sync_VerseSearch AFTER INSERT ON `VerseTranslation`
BEGIN
UPDATE VerseSearch SET text = VerseSearch.text || ' \n ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
END

这里VerseTranslation 模型有verse_id 并且VerseSearch 表有对应于每个verse_id 的数据。

但是当我在 AFTER INSERT 触发器中使用 INSERT 语句时,它正在工作 AFTER UPDATE 触发器中的 UPDATE 语句也可以正常工作: 示例:

 CREATE TRIGGER sync_VerseSearch AFTER INSERT ON `VerseTranslation`
  BEGIN
  INSERT INTO VerseSearch (verse_id, text) VALUES(NEW.verse_id + 10000, NEW.text);
  END


 CREATE TRIGGER sync_VerseSearch AFTER UPDATE ON `VerseTranslation`
  BEGIN
  UPDATE VerseSearch SET text = VerseSearch.text || ' \n ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
  END

在插入中添加了 +10000,因为 VerseSearch 表中已经存在每个对应的 verse_id(6236) 的数据,因此它不会唯一的主键约束错误(verse_id)。

问题是相反的 ACTION(INSERT 触发器中的 UPDATE 语句)不起作用;

模型结构:

VerseTranslation {
  @PrimaryKey(autogenerate=true)
  id: Int,
  verse_id: Int, // is not primary key // it is not unique, same verse_id multiple times.
  source_id: Int,
  text: String
}

VerseSearch {
  @PrimaryKey
  verse_id: Int, // here it is primary key // it's unique here
  text: String // here I want to Concat(via trigger) all values(and future insert values) in VerseTranslation.text where match verse_id
}

谢谢。

【问题讨论】:

    标签: sql sqlite database-trigger fts4


    【解决方案1】:

    触发器必须有唯一的名称。

    您还省略了 INSERT 末尾的 ;

    以下似乎包括您想要的:-

    使用:-

    -- CLEAN EVRYTHING UP
    DROP TRIGGER IF EXISTS sync_VerseSearch;
    DROP TRIGGER IF EXISTS sync_VerseSearch_ai;
    DROP TRIGGER IF EXISTS sync_VerseSearch_au;
        DROp TRIGGER IF EXISTS sync_VerrseSearch_aiu;
    DROP TABLE IF EXISTS VerseSearch;
    DROP TABLE IF EXISTS VerseTranslation;
    
    -- CREATE ITEMS
    CREATE TABLE IF NOT EXISTS VerseSearch (verse_id INTEGER PRIMARY KEY, text TEXT);
    CREATE TABLE IF NOT EXISTS VerseTranslation (verse_id INTEGER PRIMARY KEY, text TEXT);
    
    CREATE TRIGGER sync_VerseSearch_ai AFTER INSERT ON `VerseTranslation`
      BEGIN
      INSERT INTO VerseSearch (verse_id, text) VALUES(NEW.verse_id + 10000, NEW.text);
            UPDATE VerseSearch SET text = VerseSearch.text || ' \n ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
      END
    ;
    CREATE TRIGGER sync_VerseSearch_au AFTER UPDATE ON `VerseTranslation`
      BEGIN
      UPDATE VerseSearch SET text = VerseSearch.text || ' \n** ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
      END
    ;
    
        /*
        CREATE TRIGGER sync_VerseSearch AFTER INSERT ON `VerseTranslation`
            BEGIN
            UPDATE VerseSearch SET text = VerseSearch.text || ' \n ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
            END
        ;
        */
    
    -- TESTING THE TRIGGERS
        INSERT INTO VerseSearch VALUES(null,'VSFred'),(null,'VSMary'),(null,'VSAnne'),(null,'VSJohn');
        SELECT * FROM VerseTranslation;
    SELECT * FROM VerseSearch;
    
    INSERT INTO VerseTranslation VALUES(null,'Fred'),(null,'Mary'),(null,'Anne'),(null,'John');
    SELECT * FROM VerseTranslation;
    SELECT * FROM VerseSearch;
    UPDATE VerseTranslation SET text = text||'**TEST**' WHERE NOT instr(text,'**TEST**');
    SELECT * FROM VerseTranslation;
    SELECT * FROM VerseSearch;
    

    结果

    第一个选择:-

    • 暂无翻译

    第二次选择:-

    • 添加的搜索没有触发

    翻译后第三次选择:-

    - 添加了翻译,因此将触发搜索更改

    第 4 次搜索因触发而更改和添加

    更新了第 5 次翻译

    添加了第 6 次超出范围的搜索

    替代方案:-

    CREATE TRIGGER sync_VerseSearch_ai AFTER INSERT ON `VerseTranslation`
      BEGIN
      INSERT INTO VerseSearch (verse_id, text) VALUES(NEW.verse_id + 10000, NEW.text);
      UPDATE VerseSearch SET text = VerseSearch.text || ' \n ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id;
      END
    ;
    CREATE TRIGGER sync_VerseSearch_au AFTER UPDATE ON `VerseTranslation`
      BEGIN
      UPDATE VerseSearch SET text = VerseSearch.text || ' \n** ' || NEW.text WHERE VerseSearch.verse_id = NEW.verse_id + 10000;
      END
    ;
    
    • 这可能更合适,因为它们将被排序为 INSERT 然后 UPDATE。

    【讨论】:

    • 在我的问题中,第一个 SQL 触发器(在 AFTER INSERT 触发器中更新数据)不起作用,我希望它起作用。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    相关资源
    最近更新 更多