【问题标题】:Deletion CTE's in transaction is failing to remove duplicate records删除 CTE's in transaction 无法删除重复记录
【发布时间】:2018-09-28 02:28:10
【问题描述】:

Postgresql 10.1

错误:重复键值违反唯一约束“doctorbilling_encounter_unique” DETAIL: Key (encounter_recid, uid)=(1, 39) 已经存在。

我在这里尝试执行以下操作:

-在父 common_procedure 表中,我希望将描述从“so is this”更改为“this is a test”。这很容易导致 common_procedure 表中的冲突,如果它导致两条记录具有相同的描述,因此第一个 CTE 旨在消除 common_procedure 表中的所有冲突。

-第一个 CTE 旨在删除 common_procedure 表中的任何冲突,并从被删除的记录以及被保留的记录中返回 UID。

-第二个 CTE 旨在将引用从(现已删除)common_procedure 记录移动到保留的 common_procedure 记录(好的)。

-最后的 Delete 旨在清除医生帐单表中产生的任何重复项。

这失败了!我所做的每一次尝试都会导致上述错误。似乎语句的删除方面总是发生在插入之前,因此表处于错误状态。

可以这样做吗?

感谢任何帮助或想法。

BEGIN;

    SET CONSTRAINTS ALL DEFERRED;

    UPDATE common_procedures cp
    SET description = 'this is a test'          
    WHERE cp.description ='so is this';   


    WITH _t(bad_uid, good_uid) AS (
        DELETE FROM
            common_procedures a
                USING common_procedures b
        WHERE
            a.recid > b.recid             
            AND a.description = b.description
        RETURNING a.uid, b.uid
    ),
    _t1 AS (
        UPDATE doctor_billing
        SET uid = _t.good_uid
        FROM _t
        WHERE uid = _t.bad_uid          
    )
DELETE FROM
        doctor_billing a
            USING doctor_billing b, _t
    WHERE
        a.recid > b.recid             
        AND a.uid = b.uid AND a.encounter_recid = b.encounter_recid AND a.uid = _t.good_uid;

COMMIT;

这里是表定义(非常简化):

CREATE TABLE common_procedures
(
    uid integer NOT NULL,
    description text NOT NULL,
    CONSTRAINT common_procedures_description_key UNIQUE (description)
        DEFERRABLE,
    CONSTRAINT common_procedures_uid UNIQUE (uid)
)

CREATE TABLE doctor_billing
(
    encounter_recid integer NOT NULL,
    uid integer NOT NULL,
    CONSTRAINT doctorbilling_encounter_unique UNIQUE (encounter_recid, uid)
        DEFERRABLE,
    CONSTRAINT doctor_billing_procedure_fk FOREIGN KEY (uid)
        REFERENCES nova.common_procedures (uid) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE RESTRICT
        DEFERRABLE
)

【问题讨论】:

    标签: database postgresql common-table-expression


    【解决方案1】:

    呃。我相信答案已经发布在这里:https://stackoverflow.com/a/13807067/1547335 几年前。

    简而言之,使用同一张表修改cte的两个数据不应该在同一个语句中一起使用。这是上述的工作版本(使用 PetaPoco @'s)。请注意,不同表的数据修改是同时进行的,但最终的Delete语句已被分离出来。

    BEGIN;
                                                SET CONSTRAINTS ALL DEFERRED;
    
                                                UPDATE common_procedures cp
                                                SET description =UPPER(TRIM( @0 ))                  
                                                WHERE UPPER(TRIM(cp.description)) = UPPER(TRIM(@1));    
    
                                                WITH _t(bad_uid, good_uid) AS (
                                                    DELETE FROM
                                                        common_procedures a
                                                            USING common_procedures b
                                                    WHERE
                                                        a.recid > b.recid            
                                                        AND a.description = b.description
                                                    RETURNING a.uid, b.uid
                                                ),
                                                 _t2 AS (
                                                    UPDATE doctor_billing
                                                    SET uid = _t.good_uid
                                                    FROM _t
                                                    WHERE uid = _t.bad_uid
                                                ),
                                                _t3 AS (
                                                    UPDATE nurse_billing
                                                    SET uid = _t.good_uid
                                                    FROM _t
                                                    WHERE uid = _t.bad_uid
                                                )
                                                UPDATE orders
                                                SET uid = _t.good_uid
                                                FROM _t
                                                WHERE uid = _t.bad_uid;
    
                                            DELETE FROM
                                                    doctor_billing a
                                                        USING doctor_billing b
                                                WHERE
                                                    a.recid > b.recid             
                                                    AND a.uid = b.uid AND a.encounter_recid = b.encounter_recid;
    
                                            COMMIT; 
    

    【讨论】:

      猜你喜欢
      • 2021-03-17
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      相关资源
      最近更新 更多