限制主键的最大条目

Posted

技术标签:

【中文标题】限制主键的最大条目【英文标题】:Restrict maximum entries for primary key 【发布时间】:2015-02-06 15:20:11 【问题描述】:

我想要一个表,您可以在其中为主键设置最大行数(例如 3 行)。如果一个主键已经有三行,又添加了一行,则应该删除另一行。

示例:我有一个如下所示的表格:

####################################
#   PrimaryKey  |   AnotherValue   #
####################################
|    abcdef     |       123        |
|    abcdef     |       456        |
|    abcdef     |       789        |
|    xyz123     |       sdf        |
|    xyz123     |       5s6        |
|    789klm     |       w8a        |
|    789klm     |       a4d        |
____________________________________

我尝试创建一个TRIGGER,它只允许每个 PrimaryKey 最多三个条目,使用以下...

 CREATE TRIGGER maxThreeEntries AFTER INSERT ON table
   BEGIN
     DELETE FROM table WHERE (
        SELECT PrimaryKey, COUNT(PrimaryKey)
        FROM table
        GROUP BY PrimaryKey
        HAVING COUNT(PrimaryKey) > 3
     );
   END;

...无法编译。

内部SELECT - 单独使用时 - 可以很好地满足我的需要,并返回 PrimaryKey 以及相应的行数。

【问题讨论】:

你们都没有放任何旨在删除特定记录的代码,因为说明需要删除的记录的条件。但是您说,当尝试添加第四个时,只需要删除 1 个(不是全部)。所以.. 【参考方案1】:

试试这个:

CREATE TRIGGER maxThreeEntries AFTER INSERT ON table
       BEGIN
         DELETE FROM table WHERE PrimaryKey IN (
            SELECT PrimaryKey
            FROM table
            GROUP BY PrimaryKey
            HAVING COUNT(PrimaryKey) > 3
         );
       END;

您需要比较删除 WHERE 子句中的内容。您可能还想在 SELECT 语句中添加 WHERE 子句,以确保您只找到触发器寻找的主键。我不确定如何在 mysql 中执行此操作,我主要使用 SQL-Server

【讨论】:

嗨。我收到以下回复:#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'table BEGIN DELETE FROM table WHERE PrimaryKey IN ( ' at line 1 .【参考方案2】:

我找到了以下解决方案。有两个触发器。在插入触发器之前检查是否存在具有给定主键的三行。如果是这样,那么它将插入行的“primaryKey”更改为某个特定值。该行在插入触发器后被删除。

CREATE or replace TRIGGER maxThree BEFORE INSERT ON my_table for each row       
    BEGIN
        DECLARE pkc integer;
        SET @pkc := (select count(*) from my_table where primaryKey=new.primaryKey);

        if pkc>2 then
            new.primaryKey:='aaaaaaaaaa';
        end if;       
    END;

CREATE or replace TRIGGER maxThreeAI AFTER INSERT ON my_table 
    BEGIN
        delete from my_table where primaryKey='aaaaaaaaaa';
    END;

此解决方案有一个限制。我们正在为 primaryKey 选择一些特定的值。我选择了'aaaaaaaaaa'。但是,如果您要插入具有此类 primaryKey 的行,则不会插入该行。

向该表插入行后会发生什么:

insert into my_table(primaryKey, anotherValue) values('abc', '111');  -- row inserted
insert into my_table(primaryKey, anotherValue) values('abc', '222');  -- row inserted
insert into my_table(primaryKey, anotherValue) values('abc', '333');  -- row inserted

insert into my_table(primaryKey, anotherValue) values('abc', '444');  
-- this fourth row will not be inserted. 
-- First trigger will change 'primaryKey' value of this row to 'aaaaaaaaaa' 
-- and row ('aaaaaaaaaa', '444')  will be inserted.
-- But then second insert will call 
delete from my_table where primaryKey='aaaaaaaaaa';
-- and this command will delete this fourth row.

所以在这四次插入之后,表中只有前三行。

我声明了变量“pkc”。在插入另一行之前,我计算了具有与该新行的“primaryKey”相同的primaryKey 的行。此计数保存到变量 pkc(选择进入)。然后我在 if 语句中使用这个变量。

【讨论】:

嗨。感谢您的解决方案。一件小事:如果计数大于三,我不想删除所有行,而是删除行,直到每个主键的行数等于三。有什么建议吗? @StefanSurkamp 在我的解决方案中,并非所有行都被删除,但仅删除了这一附加行。 @StefanSurkamp 我编辑了我的答案并描述了它是如何工作的。 仍然无法正常工作。我确定我必须使 pkc number; 适应我的价值观......也许你可以澄清这部分代表什么? @StefanSurkamp 我为我的回答添加了更多解释

以上是关于限制主键的最大条目的主要内容,如果未能解决你的问题,请参考以下文章

可以存储在 HashMap 中的键(对象)数量的理论限制?

是否可以限制 html 中文本输入的每分钟最大条目数?

错误 #1062 主键的 Mysql 重复条目

如何避免没有主键和唯一键的重复条目?

MySQL 错误:主键的重复条目“xxx”

SQL:选择另一个表中没有复合主键的条目