2016-03-02 85 views
1

我想按特定顺序删除行。我尝试了帖子How do I delete a fixed number of rows with sorting in PostgreSQL?中的建议,但没有任何工作。我知道他们没有工作,因为我有一个删除触发器,并看到哪一个被删除,它从来没有按照我想要的顺序去做。删除PostgresSQL中的排序

,我写的测试是这样的:

create table test1 (
    th text, 
    co text, 
    ty text); 

CREATE OR REPLACE FUNCTION testfunc() RETURNS TRIGGER 
LANGUAGE plpgsql 
AS $$ 

DECLARE modified_row test1%ROWTYPE; 
BEGIN 

    IF TG_OP = 'DELETE' THEN 
    modified_row := OLD; 
ELSE 
    modified_row := NEW; 
END IF; 
raise notice 'opearation: %, co: %', TG_OP, modified_row.co; 
    RETURN modified_row; 
END; 
$$; 

CREATE TRIGGER trigger_test1 
BEFORE DELETE OR INSERT on test1 
FOR EACH ROW 
EXECUTE PROCEDURE testfunc(); 

insert into test1 (th, co, ty) values ('t1', 'c1', 'p'), ('t2', 'c2','p'), ('t2', 'c3','p'), ('t2', 'c4','p'); 
delete from test1 where ctid in (select ctid from test1 order by co desc); 

上面的delete语句是最高的投票,并在上面后接受的答案。但对我来说,输出一直是:

注意:opearation:DELETE,CO:C1

注意:opearation:DELETE,CO:C2

注意:opearation:DELETE,CO:C3

注意:opearation:DELETE,CO:C4

这表明删除未在“合作”,我试图做的递减顺序进行。我在这里错过了什么吗?

注意:忘记插入顺序,我只关心删除顺序。我不能在上面的帖子中提出这个问题,因为我没有足够的声望发表评论。

+1

您可以创建一个'CURSOR'并逐个删除吗? –

+0

如果在删除子查询中使用LIMIT 1,则会先删除最后一个。如果你在循环中这样做,你会得到你想要的订单。 – hruske

+0

好吧,我会尝试那些。但是没有办法对删除进行排序呢? – ski

回答

2

我能想到的唯一方法是在循环中删除。 下面是一个使用光标的例子:

DO $$ 
DECLARE 
    test1_row test1%ROWTYPE;  
BEGIN 
    FOR test1_row IN SELECT * FROM test1 ORDER BY co DESC 
    LOOP 
     DELETE FROM test1 WHERE th = test1_row.th AND co = test1_row.co AND ty = test1_row.ty; 
    END LOOP; 
END $$ 

注:

DO $$ 
DECLARE 
    test1_row test1%ROWTYPE; 
    DECLARE cur CURSOR FOR SELECT * FROM test1 ORDER BY co DESC FOR UPDATE; 

BEGIN 
    FOR test1_row IN cur 
    LOOP 
     DELETE FROM test1 WHERE CURRENT OF cur; 
    END LOOP; 
END $$ 

没有游标的情况的一个例子上面的WHERE条件DELETE说法是不可靠的,因为test1表没有主/唯一键。在其他情况下,您可以使用:WHERE id = row.id

+0

感谢pumbo,作品完美。 – ski