如何在我的sql代码中使用'begin atomic'函数来创建触发器?

时间:2017-07-24 11:11:39

标签: mysql triggers

我的代码

 delimiter //
 create table NumAppApk as select count(distinct App_Name) as AppNum, count(ID) as ApkNum 
 from market_app_metadata;

 create trigger numCounter before insert on market_app_metadata
 for each row
 begin
     set @tmp = (select count(*) from market_app_metadata where App_Name = new.App_Name);
     update NumAppApk set ApkNum = ApkNum + 1;
     if @tmp < 1 then
         update NumAppApk set AppNum = AppNum + 1;
     end if;
 end;
 //

一些定义和目的

  1. market_app_metadata

    此表包含以下列:App_Name表示应用程序的真实名称,Package_Name表示apk的包名称。所以情况是同一个apk的不同版本有不同的apks。

  2. NumAppApk

    因此,此表设置为计算market_app_metadata表中有多少个app和apks。但由于该表一直在更新,因此我想使用mysql trigger从表NumAppApk快速查询实时数据

  3. 难度

    要计算App_Name不同计数,每次有新行时,我都会使用

    set @tmp = (select count(*) from market_app_metadata where App_Name = new.App_Name);
    

    计算表中有多少个应用与此新应用相同的名称。

    因此,如果@tmp == 0,则表示新行代表新的应用。

    我无法找到我的方式的逻辑错误,但结果是错误的

    The wrong result

    事实证明条件语句if @tmp < 1 then不起作用,或者我认为我应该使用begin atomic来确保原子性。

    总结 - 两个问题

    • 我的代码中是否存在逻辑错误?

    • 如何在MySQL Server 5.7.18中使用begin atomic? (此语句将导致错误mysql - ERROR 1064 (42000): You have an error in your SQL syntax ...。)

1 个答案:

答案 0 :(得分:0)

我不认为你的逻辑是错误的,或者代码错了,这就是为什么

MariaDB [sandbox]> /*
   /*> DROP TABLE IF EXISTS market_app_metadata;
   /*> CREATE TABLE market_app_metadata( id INT AUTO_INCREMENT PRIMARY KEY, APP_NAME VARCHAR(10));
   /*> create table numappapk (id int default 1,appnum int,apknum int);
   /*> */
MariaDB [sandbox]> TRUNCATE TABLE OCCURSRESULTS;
Query OK, 0 rows affected (0.18 sec)

MariaDB [sandbox]> truncate table market_app_metadata;
Query OK, 0 rows affected (0.20 sec)

MariaDB [sandbox]> drop table if exists numappapk;
Query OK, 0 rows affected (0.10 sec)

MariaDB [sandbox]>
MariaDB [sandbox]>
MariaDB [sandbox]> INSERT INTO market_app_metadata(APP_NAME) VALUES ('AAA'),('BBB'),('AAA');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [sandbox]> create table NumAppApk as select count(distinct App_Name) as AppNum, count(ID) as ApkNum
    ->  from market_app_metadata;
Query OK, 1 row affected (0.28 sec)
Records: 1  Duplicates: 0  Warnings: 0

MariaDB [sandbox]>
MariaDB [sandbox]> SELECT * FROM NUMAPPAPK;
+--------+--------+
| AppNum | ApkNum |
+--------+--------+
|      2 |      3 |
+--------+--------+
1 row in set (0.00 sec)

Numappapk正如我所料。

如果我们然后创建触发器

 DROP TRIGGER IF EXISTS numcounter;
 delimiter //
 #create table NumAppApk as select count(distinct App_Name) as AppNum, count(ID) as ApkNum 
 #from market_app_metadata;

 create trigger numcounter before insert on market_app_metadata
 for each row
 begin
    insert into occursresults(msg) values ('start');
     #set tmp = IFNULL((select count(*) from market_app_metadata where App_Name = new.App_Name),0);
     set @tmp = (select count(*) from market_app_metadata where App_Name = new.App_Name);
     insert into occursresults(msg) values (concat('tmp:', ifnull(@tmp,'null'),' newappname:', ifnull(new.app_name,'newapp is null')));
     #select appnum,apknum into _appnum,_apknum from NumAppApk;

     set @appnum = (select appnum from NumAppApk);
     set @apknum = (select apknum from NumAppApk);
      insert into occursresults(msg) values (concat(' before update apknum appnum:',ifnull(@appnum,0),' apknum:',ifnull(@apknum,0)));
     update NumAppApk set ApkNum = ApkNum + 1;
     if @tmp < 1 then
            insert into occursresults(msg) values (concat(ifnull(new.app_name,'newapp is null'), ' tmp < 1'));
         update NumAppApk set AppNum = AppNum + 1;
     end if;
 end  //

 DELIMITER ;

请注意,discoverresults表仅用于调试目的

然后我们这样做

INSERT INTO market_app_metadata(APP_NAME) VALUES ('CCC'),('AAA');
select * from market_app_metadata;
select count(distinct app_name) from market_app_metadata;
SELECT * FROM NUMAPPAPK;
select * from occursresults;

我们得到了这个

MariaDB [sandbox]> select * from market_app_metadata;
+----+----------+
| ID | APP_NAME |
+----+----------+
|  1 | AAA      |
|  2 | BBB      |
|  3 | AAA      |
|  4 | CCC      |
|  5 | AAA      |
+----+----------+
5 rows in set (0.00 sec)

MariaDB [sandbox]> select count(distinct app_name) from market_app_metadata;
+--------------------------+
| count(distinct app_name) |
+--------------------------+
|                        3 |
+--------------------------+
1 row in set (0.00 sec)

MariaDB [sandbox]> SELECT * FROM NUMAPPAPK;
+--------+--------+
| AppNum | ApkNum |
+--------+--------+
|      3 |      5 |
+--------+--------+
1 row in set (0.00 sec)

MariaDB [sandbox]> select * from occursresults;
+----+-----------------------------------------+
| id | msg                                     |
+----+-----------------------------------------+
|  1 | start                                   |
|  2 | tmp:0 newappname:CCC                    |
|  3 |  before update apknum appnum:2 apknum:3 |
|  4 | CCC tmp < 1                             |
|  5 | start                                   |
|  6 | tmp:2 newappname:AAA                    |
|  7 |  before update apknum appnum:3 apknum:4 |
+----+-----------------------------------------+
7 rows in set (0.00 sec)

Numappapk正如我所料,并且结果显示if tmp&lt;正在为'CCC'执行1个代码。

如果我使用的模型与您的模型不一致或者最终结果与我的模型不符,请查看和评论。