2013-10-29 67 views
0

我試圖響應在一個表(A)中插入一行以基於第三個表的值創建或更新第二個表(B)中的多個行(C)(可以加入第一個)。SQLite觸發器插入/替換多行多表

我有以下的構造,

CREATE TRIGGER MyTrigger AFTER INSERT ON A 
    BEGIN 
     INSERT OR REPLACE INTO B (ID, T1, T2, Role) 
     VALUES 
     (
      (SELECT ID FROM C WHERE R1 = NEW.R1), 
      NEW.T1, 
      B.T2, -- The existing row's T2 
      (SELECT Role FROM C WHERE R1 = NEW.R1), 
     ) 
    END; 

Table A has columns ID, T1, R1 
Table B has columns ID, T1, T2, Role 
Table C has columns ID, R1, R2, Role 

我至少有兩個問題,我嘗試在構成觸發

  1. 我不知道如何引用在替換B的現有值case,因此「B.T2」
  2. 我不知道如何在表B中執行INSERT/REPLACE時引用表C中同一行的多個列(R1,角色)。

感謝您對此進行整理的任何幫助。

+0

使用'SELECT ... FROM B,其中ROWID = NEW.ROWID',而不是'VALUES(...)' –

+0

你最好寫一個答案,並接受它!只是爲了避免保持開放的問題。 –

回答

1

我能夠在SELECT上使用LEFT OUTER JOIN,因此無論是否存在現有行,都可以命名所有需要的值。

CREATE TRIGGER MyTrigger AFTER INSERT ON A 
    BEGIN 
     INSERT OR REPLACE INTO B (ID, T1, T2, Role) 
      SELECT 
       C.ID, 
       NEW.T1, 
       B.T2, 
       C.Role 
      FROM C LEFT OUTER JOIN B ON C.ID = B.ID WHERE C.R1 = NEW.R1; 
    END; 
1

使用SELECT而不是VALUES

CREATE TRIGGER MyTrigger AFTER INSERT ON A BEGIN 
    INSERT OR REPLACE INTO B (ID, T1, T2, Role) SELECT 
     (SELECT ID FROM C WHERE R1 = NEW.R1), 
     NEW.T1, 
     B.T2, 
     (SELECT Role FROM C WHERE R1 = NEW.R1) 
     FROM B WHERE ROWID=NEW.ROWID 
    END; 
+0

鑑於NEW引用A中的一行,是不是「FROM B WHERE ROWID = NEW.ROWID」註定要失敗?無論如何,我不能讓SELECT以這種形式工作,包括嘗試在哪裏選擇常量值。一個使用VALUES形式直接插入常量的觸發器工作正常,但這隻能驗證我的測試裝備。我仍然受到上述兩個問題的困擾。 – JBJB

+0

爲什麼'B.rowid'與'A.rowid'相同?對於新插入的'A'記錄,在'B'中永遠不會找到'NEW.rowid',所以外層的SELECT不會返回任何內容。 –

0

要找到B記錄,只需使用子查詢像你與C做。 搜索的B.ID值與您嘗試插入的值相同。

CREATE TRIGGER MyTrigger 
AFTER INSERT ON A 
BEGIN 
    INSERT OR REPLACE INTO B (ID, T1, T2, Role) 
    VALUES 
    (
     (SELECT ID FROM C WHERE R1 = NEW.R1), 
     NEW.T1, 
     (SELECT T2 FROM B WHERE ID = (SELECT ID FROM C WHERE R1 = NEW.R1)), 
     (SELECT Role FROM C WHERE R1 = NEW.R1) 
    ); 
END; 
+0

這是朝正確方向邁出的一步,給我一個單一的,形狀正確的記錄。現在我的挑戰是能夠處理表C涉及多行的情況 - 與觸發器有關的第二個問題。也就是說,我的測試用例在C中有兩行,其中R1 = NEW.R1。現在,我只在C中爲C中的第一行插入一行。這非常合理,因爲內部SELECT只能提供單個值。所以我假設SQLite正在返回第一個值。 – JBJB