2012-11-28 67 views
2

我明白準備好的語句不允許觸發器內,但我不明白我可以做我想做的事情,所以任何替代品/解決方法將不勝感激。動態SQL內觸發替代

DELIMITER $$ 

CREATE TRIGGER trigger1 after INSERT on table1 
FOR EACH ROW 
begin 
DECLARE a varchar(30); 
DECLARE b varchar(30); 
DECLARE c varchar(30); 
DECLARE d varchar(30); 
SET a = new.Col1; 
SET b = new.Col2; 
SET c = (select Col4 from table2 where Col3=new.Col3); 
SET d = concat('select ',a,' from table3 where yq=',c,' and xz=',b); 
insert into table4 values (d); 
end 
$$ 

DELIMITER; 

所以發生的:一個行插入和3個值是從該行,Col1Col2,並new.Col3拍攝。 new.Col3用於從不同的表中獲取一行,然後與Col2一起使用來搜索第三個表,我需要的值是。 Col1是問題所在,因爲它應該是d的動態生成列名稱,但這不起作用。 因此,顯然目前我所得到的是一個d中的select語句的字符串,這是我所期望的,但我無法執行該語句,因爲這是不允許的。 那麼我怎樣才能在select語句中獲得動態生成的列名?

表1

Col1 | Col2 | Col3 
c | d | x 
a | e | y 
b | e | z 
b | f | x 

表2

Col3 | Col4 
x | 1 
y | 2 
z | 3 

表3

a | b | c | xz | yq 
1a | 1b | 1c | d | 1 
2a | 2b | 2c | d | 2 
3a | 3b | 3c | d | 3 
4a | 4b | 4c | e | 1 
5a | 5b | 5c | e | 2 
6a | 6b | 6c | e | 3 
7a | 7b | 7c | f | 1 
8a | 8b | 8c | f | 2 
9a | 9b | 9c | f | 3 

我想要的結果是從圖1A-9c上。

我曾考慮更改表模式,以便觸發器中的列名可以修復,但這是最後的手段,因爲這會導致其他代碼位出現問題。

回答

2

你將不得不完全放棄預處理語句和動態SQL的想法,只是痛苦地做一些IF..THEN聲明:

DELIMITER $$ 

CREATE TRIGGER trigger1 after INSERT on table1 
FOR EACH ROW 
begin 
DECLARE a varchar(30); 
DECLARE b varchar(30); 
DECLARE local_c varchar(30); 
DECLARE d varchar(30); 
SET a = new.Col1; 
SET b = new.Col2; 
SET local_c = (select Col4 from table2 where Col3=new.Col3); 
IF local_c = 'a' THEN 
    select a into d from table3 where yq=local_c and xz=b; 
END IF; 
IF local_c = 'b' THEN 
    select b into d from table3 where yq=local_c and xz=b; 
END IF; 
IF local_c = 'c' THEN 
    select c into d from table3 where yq=local_c and xz=b; 
END IF; 
IF ISNULL(d) = 0 THEN 
    insert into table4 values (d); 
END IF; 
end 
$$ 

DELIMITER; 
+0

好主意,雖然相當可怕,不得不訴諸於此,但我沒有想到這樣做。 – mrmryb

+0

這是醜陋的,詳細的,可能會維護很多,但是真正的唯一方法是根據MySQL的限制來做到這一點。 –

0

嘗試下面用事先準備好的聲明:

PREPARE myStmt FROM 
'concat(insert into table4 values (', 
      'select ', 
      a, 
      ' from table3 where yq=', 
      c, 
      ' and xz=', 
      b, 
      '))'; 
EXECUTE myStmt; 
+1

動態SQL ISN」 t在觸發器內允許,這是我遇到的問題。我需要一種方法來解決這個問題。 – mrmryb