programing

업데이트 시 입력 키 중복 방지 방법

javaba 2022. 10. 27. 23:20
반응형

업데이트 시 입력 키 중복 방지 방법

문제 설명

연결된 3개의 기본 키의 마지막 기본 키는 업데이트하지 않습니다.그러나 문제는 첫 번째와 두 번째 기본 키가 여러 레코드에 대해 동일할 수 있다는 것입니다.이 경우 새로운 값을 설정할 때 해당 문제를 피하기 위해 하위 요청을 사용하더라도 입력 키가 중복됩니다.

일부 코드

스키마

create table llx_element_contact
(
    rowid             int auto_increment
        primary key,
    datecreate        datetime           null,
    statut            smallint default 5 null,
    element_id        int                not null,
    fk_c_type_contact int                not null,
    fk_socpeople      int                not null,
    constraint idx_element_contact_idx1
        unique (element_id, fk_c_type_contact, fk_socpeople)
)

업데이트 요청

이 요청은 중복 키 오류를 반환합니다.

update llx_element_contact lec
set lec.fk_socpeople = 64
where 
-- Try to avoid the error by non including the values that are the same
(select count(*)
 from llx_element_contact ec
 where ec.fk_socpeople = 64
   and ec.element_id = lec.element_id
   and ec.fk_c_type_contact = lec.fk_c_type_contact) = 0

테스트 데이터

rowid, datecreate, statut, element_id, fk_c_type_contact, fk_sockpeople
65,2015-08-31 18:59:18,4,65,160,30
66,2015-08-31 18:59:18,4,66,159,12
67,2015-08-31 18:59:18,4,67,160,12
15283,2016-03-23 11:47:15,4,6404,160,39
15284,2016-03-23 11:51:30,4,6404,160,58

3D 멤버에 동일한 값을 할당하려고 하므로 고유한 제약 조건을 가진 다른 멤버 2개만 선택해야 합니다.동일한 두 멤버를 가진 행이 하나 이상 존재하지 않아야 합니다.

update llx_element_contact lec
set lec.fk_socpeople = 64
where 
-- Try to avoid the error by non including the values that are the same
(select count(*)
 from llx_element_contact ec
 where ec.element_id = lec.element_id
   and ec.fk_c_type_contact = lec.fk_c_type_contact) <=1

또는

update llx_element_contact lec
set lec.fk_socpeople = 64
where 
-- Try to avoid the error by non including the values that are the same
 not exists (select 1
 from llx_element_contact ec
 where ec.element_id = lec.element_id
   and ec.fk_c_type_contact = lec.fk_c_type_contact
   and lec.fk_socpeople != ec.fk_socpeople)

다음을 사용할 수 있습니다.

예방할 수 있습니다.unique사용으로 경합하다left join대응하는 행이 아직 존재하지 않는지 확인합니다.

update llx_element_contact lec left join
       (select element_id, fk_c_type_contact
        from llx_element_contact lec2
        where lec2.fk_socpeople = 64
        group by element_id, fk_c_type_contact
       ) lec2
       using (element_id, fk_c_type_contact)
    set lec.fk_socpeople = 64
    where lec2.element_id is null;

쿼리에 설명되지 않은 추가 논리가 있습니다.그것은 당신이 요구하는 것에 필요하지 않다.

WITH cte AS (
SELECT rowid, 
       SUM(fk_socpeople = 64) OVER (PARTITION BY element_id, fk_c_type_contact) u_flag,
       ROW_NUMBER() OVER (PARTITION BY element_id, fk_c_type_contact ORDER BY datecreate DESC) u_rn
FROM llx_element_contact
)
update llx_element_contact lec
JOIN cte USING (rowid)
set lec.fk_socpeople = 64 
where cte.u_flag = 0
  AND cte.u_rn = 1

https://dbfiddle.uk/?rdbms=http_8.0&http=08e20328ccct7716084ce9d78816b0

언급URL : https://stackoverflow.com/questions/67687607/how-to-prevent-duplicate-entry-key-when-update

반응형