【问题标题】:Dynamic SQL within trigger alternative触发器备选方案中的动态 SQL
【发布时间】:2012-11-28 17:17:35
【问题描述】:

我了解触发器中不允许使用准备好的语句,但我看不出还有什么方法可以做我想做的事,因此非常感谢任何替代方案/解决方法。

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 个值,Col1Col2new.Col3new.Col3 用于从不同的表中获取一行,然后与Col2 一起用于搜索我需要的值所在的第三个表。 Col1 是问题所在,因为它应该是 d 的动态生成的列名,但这不起作用。 所以很明显,目前我得到的只是d 中的选择语句字符串,这是我所期望的,但我无法执行该语句,因为这是不允许的。 那么如何将动态生成的列名放入 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。

我考虑过更改表架构,以便可以修复触发器中的列名,但这是最后的手段,因为它会导致其他代码位出现问题。

【问题讨论】:

    标签: mysql sql triggers


    【解决方案1】:

    您将不得不完全放弃准备好的语句和动态 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;
    

    【讨论】:

    • 好主意,虽然不得不求助于这个方法很可怕,但我没想过那样做。
    • 这是丑陋的,冗长的,并且可能需要大量维护,但鉴于 MySQL 的限制,这确实是唯一的方法。
    【解决方案2】:

    尝试使用如下准备好的语句:

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

    【讨论】:

    • 触发器中不允许使用动态 SQL,这就是我遇到的问题。我需要一种方法来解决这个问题。
    • mySQL 不允许在触发器和函数中创建动态 SQL
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 2017-06-05
    • 2017-06-28
    • 2014-02-02
    • 2017-03-04
    • 1970-01-01
    • 2013-03-09
    • 2015-06-28
    相关资源
    最近更新 更多