【问题标题】:Set insert trigger - value to highest value in column + 1将插入触发器 - 值设置为列中的最大值 + 1
【发布时间】:2018-10-26 19:09:55
【问题描述】:

我有一个包含以下列的列表

lists:
- id
- category_id
- name
- sort_order

向表中添加新行时,我想将排序顺序的值设置为最高排序顺序值 + 1,其中 category_id 与新行的 category_id 相同。有没有办法做到这一点?

更新 因此,在建议创建插入触发器时,我尝试了这个

CREATE FUNCTION set_list_sort_order()
RETURNS trigger AS $$
BEGIN
  NEW.sort_order := select (select sort_order from lists where category_id = NEW.category_id order by sort_order DESC limit 1) + 1
  RETURN NEW;
END 
$$ LANGUAGE 'plpgsql';

CREATE TRIGGER set_list_sort_order_trigger
BEFORE INSERT ON lists
FOR EACH ROW
EXECUTE PROCEDURE set_list_sort_order()

但我收到此错误:

ERROR:  syntax error at or near "select"
LINE 4:   NEW.sort_order := select (select sort_order from lists w...

【问题讨论】:

  • 您是否尝试过使用插入触发器?
  • 当你有两个同时插入时会发生什么?他们应该得到相同的值吗?
  • 您应该使用序列来生成这些数字。任何使用 max() + 1 的方法要么非常缓慢,要么无法扩展,要么就被破坏了。
  • @a_horse_with_no_name 序列可以基于另一个列值吗?就像我的示例中的 category_id 一样?

标签: sql postgresql


【解决方案1】:

您可以设置触发器。也可以直接在insert中设置逻辑:

insert into lists (category_id, name, sort_order)
    select category_id, name,
           coalesce(max(sort_order) + 1, 1)
    from (values (?, ?)) v(category_id, name) left join
         lists l
         using (category_id)
    group by v.category_id, v.name;

请注意,这样的查询可能有竞争条件。所以,你可能想走使用触发器的路线。

【讨论】:

  • thxs 伙计,我该如何设置具有指定逻辑的触发器?
【解决方案2】:

您可以尝试使用以下方式创建存储过程:

DEClARE @category_id INT = 1

;WITH NextNum AS 
(
    SELECT 
            CASE 
                WHEN MAX(Table1.sort_order) IS NULL THEN 1 
                ELSE MAX(Table1.sort_order) + 1
            END AS NextValue 
    FROM Table1 AS Table1
    WHERE Table1.category_id = @category_id
) 
INSERT INTO Table1
(
    id
    category_id
    name
    sort_order
)
SELECT  @id, 
        @category_id
        @name 
        NextNum.NextValue
    FROM NextNum

【讨论】:

  • 这对 Postgres 无效
猜你喜欢
  • 2014-10-30
  • 2016-01-29
  • 2013-04-12
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
相关资源
最近更新 更多