programing

ORA-30926: 소스 테이블에서 안정적인 행 집합을 가져올 수 없습니다.

golfzon 2023. 3. 25. 12:06
반응형

ORA-30926: 소스 테이블에서 안정적인 행 집합을 가져올 수 없습니다.

나 이제...

ORA-30926: 소스 테이블에서 안정적인 행 집합을 가져올 수 없습니다.

다음 쿼리로 이동합니다.

  MERGE INTO table_1 a
      USING 
      (SELECT a.ROWID row_id, 'Y'
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

table_1했습니다.src데이터도 있습니다.

이 오류는 왜 발생하며 어떻게 해결할 수 있습니까?

이 문제는 보통 USING 절에 지정된 쿼리의 중복으로 인해 발생합니다.이것은 아마도 Tab이LE_A는 부모 테이블이며 동일한 ROWID가 여러 번 반환됩니다.

쿼리에서 DISTINT를 사용하면 문제를 빠르게 해결할 수 있습니다(실제로 'Y'가 상수 값인 경우 쿼리에 입력할 필요도 없습니다).

쿼리가 올바르다고 가정하면(테이블을 알 수 없음), 다음과 같은 작업을 수행할 수 있습니다.

  MERGE INTO table_1 a
      USING 
      (SELECT distinct ta.ROWID row_id
              FROM table_1 a ,table_2 b ,table_3 c
              WHERE a.mbr = c.mbr
              AND b.head = c.head
              AND b.type_of_action <> '6') src
              ON ( a.ROWID = src.row_id )
  WHEN MATCHED THEN UPDATE SET in_correct = 'Y';

대상 테이블의 동일한 행을 여러 번 업데이트하려고 합니다.제가 개발한 merge 스테이트먼트에서도 같은 문제가 발생했습니다.병합 실행 시 업데이트가 동일한 레코드에 두 번 이상 닿지 않도록 하십시오.

일반적인 경우 오류 ORA-30926을 해결하기 위한 DISTINT 사용에 대한 추가 설명:

USING() 절에 의해 지정된 데이터 세트에 조인 열(ON() 절의 열)의 중복된 값이 없는지 확인해야 합니다.

USING 절이 키만 선택하는 OP의 예에서는 USING 절에 DISTINT을 추가하는 것으로 충분했습니다.단, 일반적인 경우 USING 절은 대조할 키 열과 UPDATE ... SET 절에서 사용할 속성 열의 조합을 선택할 수 있습니다.따라서 일반적인 경우 USING 구에 DISTINT를 추가해도 동일한 키에 대해 다른 업데이트 행이 허용되며, 이 경우에도 ORA-30926 오류가 발생합니다.

이것은 Dcookie의 답변과 Tagar의 답변의 포인트 3.1을 상세하게 정리한 것으로, 제 경험상으로는 금방 알 수 없을지도 모릅니다.

ORA-30926 오류 문제 슈팅 방법(문서 번호 471956.1)

1) 불합격 스테이트먼트를 특정한다.

세션 세트 이벤트 '30926 트레이스 이름 오류 스택 레벨 3' 변경;

또는

시스템 세트 이벤트 '30926 trace name errorstack off' 변경;

UDUMP 내의 .trc 파일을 감시합니다.

2) SQL 문을 찾은 후 (아마도 쿼리 실행 계획을 확인하기 위해 explain plan 또는 tkprof를 사용하여) 정확한지 확인하고 최근 이 작업이 수행되지 않은 경우 해당 테이블의 통계정보를 분석 또는 계산한다.인덱스를 재구축(또는 삭제/재작성)하는 것도 도움이 될 수 있습니다.

3.1) SQL 문이 MERGE입니까? USING 절에 의해 반환된 데이터를 평가하여 결합에 중복된 값이 없는지 확인합니다.결정론적 where 절을 포함하도록 병합 문을 수정합니다.

3.2) 이것은 뷰를 통한 UPDATE 스테이트먼트입니까?이 경우 뷰 결과를 표로 채우고 표를 직접 업데이트해 보십시오.

3.3) 테이블에 트리거가 있습니까?아직 실패하는지 확인하기 위해 비활성화해 보십시오.

3.4) 스테이트먼트에 'IN-Subquery'에 병합할 수 없는 뷰가 포함되어 있습니까?따라서 쿼리에 "FOR UPDATE" 절이 있는 경우 중복된 행이 반환될 수 있습니다."Bug 2681037"

3.5) 테이블에 미사용 컬럼이 있습니까?이것들을 드롭 하면, 에러가 방지될 가능성이 있습니다.

4) SQL을 수정해도 오류가 해결되지 않는 경우, 특히 체인으로 연결된 행이 있는 경우 문제가 테이블에 있을 수 있습니다. 4.1) SQL에서 사용되는 모든 테이블에서 'ANYLYZE TABLE VALIDATE STRUCTURE CASCADE' 문을 실행하여 테이블 또는 인덱스에 파손이 없는지 확인합니다.4.2).테이블상의 체닝된 ROWS 또는 이행된 ROWS.PCTFREE 의 올바른 설정 등, 이것을 최소한으로 억제하는 방법이 있습니다.주 122020.1 - 행 체인과 이행 4.3) 테이블이 추가로 인덱스 구성일 경우, 주 102932.1 - IOT에서의 체인된 행의 모니터링을 참조하십시오.

오늘 12c에서 오류가 발생하여 기존 답변이 모두 일치하지 않음(WHERE 절에 중복되지 않음, 비결정론적 표현 없음).Oracle의 메시지 텍스트(아래 강조)에 따르면 내 사례는 오류의 다른 가능한 원인과 관련이 있습니다.

ORA-30926: 소스 테이블에서 안정적인 행 집합을 가져올 수 없습니다.
원인: dml 액티비티가 크거나 결정적이지 않은 where 절로 인해 안정적인 행 집합을 가져올 수 없습니다.

병합은 대규모 배치의 일부이며 다수의 동시 사용자가 있는 라이브 데이터베이스에서 실행되었습니다.진술을 변경할 필요가 없었다.머지 전에 트랜잭션을 커밋한 후 개별적으로 머지를 실행한 후 다시 커밋했습니다.이 경우 메시지에서 권장되는 액션에서 해결 방법을 찾을 수 있습니다.

조치: 결정적이지 않은 구를 삭제하고 dml을 재발행합니다.

SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 -  "unable to get a stable set of rows in the source tables"
*Cause:    A stable set of rows could not be got because of large dml
           activity or a non-deterministic where clause.
*Action:   Remove any non-deterministic where clauses and reissue the dml.

오류는 중복된 레코드로 인해 발생하였습니다(16K).

는 독특한 방법으로 그것을 시도했다.

그러나 동일한 프로블을 사용하지 않고 병합을 시도했을 때 두 번째 커밋이 발생하였습니다.

merge 후 commit이 실행되지 않으면 에러가 표시됩니다.

고유하지 않으면 각 병합 작업 후에 커밋이 지정되면 쿼리가 작동합니다.

나는 몇 시간이 지나도 이것을 해결할 수 없었다.결국 2개의 테이블이 결합된 상태에서 선택을 하고 추출을 작성한 후 테이블 내의 500개 행에 대한 개별 SQL 업데이트 문을 만들었습니다.못생겼지만 몇 시간씩 꼬치꼬치 캐묻는 것보다 낫다.

앞에서 설명한 바와 같이 MERGE 스테이트먼트가 같은 행을 여러 번 갱신하려고 해도 기능하지 않을 수 있습니다(모호한 상태가 될 수 있습니다.

여기 한 가지 간단한 예가 있습니다.지정된 검색 패턴과 일치할 때 일부 제품을 찾은 것으로 표시하려는 MERGE:

CREATE TABLE patterns(search_pattern VARCHAR2(20));
INSERT INTO patterns(search_pattern) VALUES('Basic%');
INSERT INTO patterns(search_pattern) VALUES('%thing');

CREATE TABLE products (id NUMBER,name VARCHAR2(20),found NUMBER);
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',0);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',0);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',0);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',0);

MERGE INTO products p USING
(
   SELECT search_pattern FROM patterns
) o
ON (p.name LIKE o.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=1;

SELECT * FROM products;

한다면patterns테이블에는 다음이 포함됩니다.Basic%그리고.Super%패턴은 MERGE가 동작하고 처음 3개의 제품이 갱신됩니다(검출).하지만 만약patterns테이블에는 다음이 포함됩니다.Basic%그리고.%thing두 번째 제품을 두 번 업데이트하려고 하면 문제가 발생하기 때문에 MERGE가 작동하지 않습니다.일부 레코드를 여러 번 갱신해야 하는 경우 MERGE가 작동하지 않습니다.아마 당신은 왜 두 번 업데이트하지 않느냐고 물으실 겁니다!?

여기서 첫 번째 업데이트 1과 두 번째 업데이트 1은 같은 값이지만 실수로 인한 것입니다.이제 다음 시나리오를 살펴보겠습니다.

CREATE TABLE patterns(code CHAR(1),search_pattern VARCHAR2(20));
INSERT INTO patterns(code,search_pattern) VALUES('B','Basic%');
INSERT INTO patterns(code,search_pattern) VALUES('T','%thing');

CREATE TABLE products (id NUMBER,name VARCHAR2(20),found CHAR(1));
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',NULL);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',NULL);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',NULL);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',NULL);

MERGE INTO products p USING
(
   SELECT code,search_pattern FROM patterns
) s
ON (p.name LIKE s.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=s.code;

SELECT * FROM products;

이제 첫 번째 제품 이름이 일치합니다.Basic%패턴과 함께 코드로 갱신됩니다.B그러나 두 번째 제품은 두 가지 패턴과 일치하며 두 가지 코드로 업데이트할 수 없습니다.B그리고.T동시에!그래서 DB엔진이 불만입니다.탓하지 마!무엇을 하고 있는지 알고 있다!;-)

언급URL : https://stackoverflow.com/questions/2337271/ora-30926-unable-to-get-a-stable-set-of-rows-in-the-source-tables

반응형