如果触发器中不存在

发布于 2024-11-05 17:41:48 字数 1443 浏览 2 评论 0原文

我有两个表concept_access 和concept_access_log。我想创建一个触发器,每次从concept_access 中删除某些内容时都会起作用,检查日志表中是否有类似的记录,如果没有,则在从concept_access 中删除它之前插入新记录。

我修改了触发器,现在它看起来像这样:

DROP TRIGGER IF EXISTS before_delete_concept_access;
DELIMITER //
CREATE TRIGGER before_delete_concept_access
    BEFORE DELETE ON `concept_access` FOR EACH ROW
    BEGIN
        IF (SELECT 1 FROM concept_access_log WHERE map=OLD.map 
                          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) IS NULL THEN
            INSERT INTO concept_access_log (map, accesstype, startdate, stopdate)
            VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate);
        END IF;
    END//
DELIMITER ;

删除之前在concept_access 中的示例数据:

map accesstype  startdate   stopdate
1   public      NULL        NULL    
1   loggedin    2011-05-11  NULL    
1   friends     NULL        NULL    

日志表已经有前 2 行。它们与concept_access 中的完全相同。当我从 Concept_access 表中删除第一行时,我在日志表中得到以下内容:

map accesstype  startdate   stopdate
1   public      NULL        NULL    
1   loggedin    2011-05-11  NULL    
1   friends     NULL        NULL    
1   public      NULL        NULL    

虽然不应该插入任何内容,因为 (1,public,null,null) 已经存在于其中。

该表没有主键。我没有创建结构,所以不要问我为什么。更改它会破坏许多现有的功能。我只需要记录从表 concept_access 中删除的内容并将其存储在日志中而不重复。

如果有人能弄清楚出了什么问题,我将非常感激。

I have tow tables concept_access and concept_access_log. I want to create a trigger that works every time something is deleted from concept_access, check if there is similar record in log table and if not, inserts new one before it is deleted from concept_access.

I modified trigger and now it looks like this:

DROP TRIGGER IF EXISTS before_delete_concept_access;
DELIMITER //
CREATE TRIGGER before_delete_concept_access
    BEFORE DELETE ON `concept_access` FOR EACH ROW
    BEGIN
        IF (SELECT 1 FROM concept_access_log WHERE map=OLD.map 
                          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) IS NULL THEN
            INSERT INTO concept_access_log (map, accesstype, startdate, stopdate)
            VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate);
        END IF;
    END//
DELIMITER ;

Sample data in concept_access before delete:

map accesstype  startdate   stopdate
1   public      NULL        NULL    
1   loggedin    2011-05-11  NULL    
1   friends     NULL        NULL    

Log table already has first 2 rows. And they are exactly the same as in concept_access. When I delete first row from concept_access table, I get this in log table:

map accesstype  startdate   stopdate
1   public      NULL        NULL    
1   loggedin    2011-05-11  NULL    
1   friends     NULL        NULL    
1   public      NULL        NULL    

While it is not supposed to insert anything because (1,public,null,null) already exists there.

This table has no primary key. I was not creating structure, so don't ask me why. Changing it will ruin a lot of already existing functionality. I just need to keep log of what was removed from table concept_access and store it in log without duplicates.

I would really appreciate, if anyone can figure out what is going wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飞烟轻若梦 2024-11-12 17:41:48
DROP TRIGGER IF EXISTS before_delete_concept_access;
DELIMITER //
CREATE TRIGGER before_delete_concept_access
    BEFORE DELETE ON `concept_access` FOR EACH ROW
    BEGIN
        IF (SELECT COUNT(*) FROM concept_access_log WHERE map=OLD.map 
                          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) = 0 THEN
            INSERT INTO concept_access_log (map, accesstype, startdate, stopdate)
            VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate);
        END IF;
    END//
DELIMITER ;

我没有使用不存在,只是测试匹配计数是否大于0

您的代码在我的机器上运行良好,您的MySQL版本是什么?

mysql> select version();
+------------+
| version()  |
+------------+
| 5.1.56-log |
+------------+
1 row in set (0.00 sec)
DROP TRIGGER IF EXISTS before_delete_concept_access;
DELIMITER //
CREATE TRIGGER before_delete_concept_access
    BEFORE DELETE ON `concept_access` FOR EACH ROW
    BEGIN
        IF (SELECT COUNT(*) FROM concept_access_log WHERE map=OLD.map 
                          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) = 0 THEN
            INSERT INTO concept_access_log (map, accesstype, startdate, stopdate)
            VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate);
        END IF;
    END//
DELIMITER ;

I am not using not exists, just test if the match count greater than 0

your code runs well on my machine, what's your MySQL version?

mysql> select version();
+------------+
| version()  |
+------------+
| 5.1.56-log |
+------------+
1 row in set (0.00 sec)
很快妥协 2024-11-12 17:41:48

而不是

... WHERE map = OLD.map ...

--  map   OLD.map  bool
--  ---   -------  ----
--  'a'    'a'     TRUE
--  'a'    'b'     FALSE
--  'a'    NULL    FALSE
--  NULL   'b'     FALSE
--  NULL   NULL    FALSE  <-- Undesired! We want this to be TRUE

尝试 <=>,它是 MySQL 对 SQL 标准的回答 IS (NOT) DISTINCT FROM 谓词

... WHERE map <=> OLD.map ...
--  TRUE when both have the same non-NULL value or when both are NULL
--  Equivalents:
--    WHERE (map = OLD.map OR (map IS NULL AND OLD.map IS NULL))
--    WHERE (map = OLD.map OR COALESCE(map, OLD.map) IS NULL)

Instead of this

... WHERE map = OLD.map ...

--  map   OLD.map  bool
--  ---   -------  ----
--  'a'    'a'     TRUE
--  'a'    'b'     FALSE
--  'a'    NULL    FALSE
--  NULL   'b'     FALSE
--  NULL   NULL    FALSE  <-- Undesired! We want this to be TRUE

try <=>, which is MySQL's answer to the SQL standard IS (NOT) DISTINCT FROM predicate:

... WHERE map <=> OLD.map ...
--  TRUE when both have the same non-NULL value or when both are NULL
--  Equivalents:
--    WHERE (map = OLD.map OR (map IS NULL AND OLD.map IS NULL))
--    WHERE (map = OLD.map OR COALESCE(map, OLD.map) IS NULL)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文