2013-10-29 3 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 в ЗАМЕНИТЬ например, «B.T2»
  2. Я не знаю, как ссылаться на несколько столбцов (R1, Роль) из той же строки в таблице C при выполнении INSERT/REPLACE в таблице B.

Спасибо за любую помощь в сортировке этого.

+0

Использование 'SELECT ... FROM B WHERE ROWID = NEW.ROWID' вместо' VALUES (...) ' –

+0

Вы бы лучше написать ответ и принять его! Просто чтобы не открывать открытые вопросы. –

ответ

1

Я был в состоянии использовать LEFT OUTER JOIN на SELECT, так что все необходимые значения могут быть названы независимо от того, есть ли существующая строка.

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

Не «FROM B WHERE ROWID = NEW.ROWID» обречен на провал, учитывая, что NEW относится к строке в A? В любом случае я не могу заставить SELECT работать в этой форме, включая попытку, когда я выбрал постоянные значения. Триггер с прямой вставкой констант с использованием формы VALUES работал нормально, но это только проверяет мою тестовую установку. Я все еще смущен двумя перечисленными проблемами. – JBJB

+0

Почему «B.rowid» должен быть таким же, как «A.rowid»? И для новой записи INSERTed 'A',' NEW.rowid' никогда не будет найден в 'B', поэтому внешний 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. Прямо сейчас, я получаю только строку, вставленную в B для первой строки в C. Это имеет смысл, учитывая, что внутренние SELECT должны только предоставлять одно значение. Поэтому я предполагаю, что SQLite возвращает первое значение. – JBJB

Смежные вопросы