2013-10-07 2 views
0

나는 단 하나의 기록을 보장하는 다음 트리거가 필드 기본 카드를 가지고있다 = 1DB2 트리거 시간 초과

create trigger TRG_U_XSTRDCRD 
    after update on XSTOREDCARD referencing new as N old as O 
    for each row mode db2sql 
    begin atomic 
     if N.DEFAULTCARD = 1 then 
      update XSTOREDCARD 
       set DEFAULTCARD = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
    [email protected] 

나는 또한 그래서, 하나의 레코드 만 1의 EBACTIVE 필드 값이 있는지 확인하고 싶습니다 나는 이것을 시도했다.

create trigger TRG_U_XSTRDCRD 
    after update on XSTOREDCARD referencing new as N old as O 
    for each row mode db2sql 
    begin atomic 
     if N.DEFAULTCARD = 1 then 
      update XSTOREDCARD 
       set DEFAULTCARD = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
     if N.EBACTIVE = 1 then 
      update XSTOREDCARD 
       set EBACTIVE = 0 
       where USERS_ID = N.USERS_ID and ID <> N.ID; 
     end if; 
    [email protected] 

그러나 그것은 작동하지 않았다, 그것은 업데이트에 대한 몇 분 제한 시간에 결과 :

Caused by: com.ibm.db2.jcc.b.SqlException: DB2 SQL error: SQLCODE: -101, SQLSTATE: 54001, SQLERRMC: null 
at com.ibm.db2.jcc.b.zc.e(zc.java:1606) 
at com.ibm.db2.jcc.b.zc.a(zc.java:1206) 
at com.ibm.db2.jcc.a.db.h(db.java:149) 
at com.ibm.db2.jcc.a.db.a(db.java:43) 
at com.ibm.db2.jcc.a.r.a(r.java:30) 
at com.ibm.db2.jcc.a.sb.g(sb.java:152) 
at com.ibm.db2.jcc.b.zc.n(zc.java:1186) 
at com.ibm.db2.jcc.b.ad.db(ad.java:1761) 
at com.ibm.db2.jcc.b.ad.d(ad.java:2203) 
at com.ibm.db2.jcc.b.ad.V(ad.java:521) 
at com.ibm.db2.jcc.b.ad.executeUpdate(ad.java:504) 
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2595) 
... 19 more 

을 수행하는 무슨 잘못이나 방법에 대한 조언을?

건배! NFV

+0

정확한 오류 코드와 전체 메시지를 표시하십시오. – mustaccio

+0

SQLCODE -101은 시간 초과가 아닙니다. 그것은 당신이 메모리 한도 또는 다른 리소스 제한을 치고 있다는 것을 의미합니다. DB2 버전 및 플랫폼에 대해 언급하지 않으므로 더 자세한 정보를 제공 할 수는 없습니다. DBA와 상담하십시오. – mustaccio

+0

다음 페이지에서 약간의 힌트가 있습니다. http://www.dbforums.com/db2/978746-sql0954c-not-enough-storage-available-application-heap-process.html –

답변

0

this nice post을 읽은 후에 많은 사람들에게 몇 가지 업데이트를 할 수 있습니다. 동일한 테이블을 업데이트하는 사후 업데이트 트리거를 정의했습니다. 해당 사용자의 모든 행을 실제로 업데이트합니다. 사용자 당 10 개의 행이 있고 한 행에서 DEFAULTCARD 플래그가 변경되었다고 가정 해 보겠습니다. 즉, 업데이트해야하는지 여부에 관계없이 9 개의 행을 업데이트한다는 의미입니다. 그러나 큰 문제는 아니지만, 5,000,000 개의 레코드가있는 경우 업데이트 할 필요가 있더라도 4,999,999 개의 레코드 만 업데이트합니다 (예 : 이전 DEFAULTCARD 레코드).

 update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 

이 문은 1 개만 기록해야합니다. 따라서 4,999,999 개의 업데이트와 트리거 호출을 실행하는 대신 하나의 업데이트 만 가질 수 있습니다.

EBACTIVE에서도 마찬가지입니다. 더 좋은 점은 EBACTIVE와 DEFAULTCARD가 서로 다른 레코드에 대해 1이면, EBACTIVE에 대한 업데이트가 EBACTIVE에 대한 업데이트를 다시 트리거하는 DEFAULTCARD에 대한 업데이트를 트리거하므로 실제로 지저분해질 것입니다. 그래서 내가 잘못 본 것이 아니라면, 당신은 무한 루프에 있습니다.

begin atomic 
    if N.DEFAULTCARD = 1 then 
     update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 
    end if; 
    if N.EBACTIVE = 1 then 
     update XSTOREDCARD 
      set EBACTIVE = 0 
      where USERS_ID = N.USERS_ID and EBACTIVE = 1 and ID <> N.ID; 
    end if; 
[email protected] 

이 방법이 더 효과적입니다.

편집 : 두 번째

이 값이 실제로 변경하는 경우 우리는 단지, 데이터 집합을 업데이트해야 할 내 시도합니다.

begin atomic 
    if N.DEFAULTCARD = 1 and O.DEFAULTCARD != 1 then 
     update XSTOREDCARD 
      set DEFAULTCARD = 0 
      where USERS_ID = N.USERS_ID and DEFAULTCARD = 1 and ID <> N.ID; 
    end if; 
    if N.EBACTIVE = 1 and O.EBACTIVE !=1 then 
     update XSTOREDCARD 
      set EBACTIVE = 0 
      where USERS_ID = N.USERS_ID and EBACTIVE = 1 and ID <> N.ID; 
    end if; 
[email protected] 
+0

제안을 주셔서 감사합니다. 좋은 것으로 보이지만 여전히 똑같습니다. 오류 ... – nfvindaloo

+0

테이블이 얼마나 큽니까? –

+0

약 10 개의 행만! – nfvindaloo