programing

오라클 업데이트 문에서 테이블 이름 대신 하위 조회 사용

megabox 2023. 7. 23. 14:10
반응형

오라클 업데이트 문에서 테이블 이름 대신 하위 조회 사용

Oracle에서는 여러 테이블이 허용되지 않기 때문에 여러 테이블을 사용하여 업데이트할 행을 결정하는 업데이트 문을 작성해야 합니다.다음 쿼리는 "ORA-00971:SET 키워드 누락" 오류

UPDATE
  TABLE1 a,
  TABLE2 b
SET
  a.COL1 = 'VALUE'
WHERE
  a.FK = b.PK
  AND b.COL2 IN ('SET OF VALUES')

오라클에서 UPDATE 문 구문을 찾아보니 테이블 이름 대신 하위 쿼리를 사용할 수 있는 링크가 있습니다.

이렇게 쿼리를 작성하려고 하면 "ORA-01779: 키가 아닌 테이블에 매핑되는 열을 수정할 수 없습니다"라는 메시지가 표시됩니다.

UPDATE
  (
    SELECT
      a.COL1
    FROM
      TABLE1 a,
      TABLE2 b
    WHERE
      a.FK = b.PK
      AND b.COL2 IN ('SET OF VALUES')
  ) update_tbl
SET
  update_tbl.COL1 = 'VALUE'

대신 EXISTES 문을 사용하여 쿼리(아래 표시)를 다시 작성했는데, 잘 작동하지만 여전히 어떻게 수행되는지 알고 싶습니다.

UPDATE
  TABLE1 update_tbl
SET
  update_tbl.COL1 = 'VALUE'
WHERE
  EXISTS (
    SELECT
      1
    FROM
      TABLE1 a
      TABLE2 b
    WHERE
      a.FK = b.PK
      AND b.COL2 IN ('SET OF VALUES')
      AND update_tbl.PK = a.PK
  )

감사합니다! - 네이트

다른 옵션:

UPDATE TABLE1 a
SET a.COL1 = 'VALUE'
WHERE a.FK IN
( SELECT b.PK FROM TABLE2 b
  WHERE b.COL2 IN ('SET OF VALUES')
)

두 번째 예는 (a) 뷰에 TABLE1의 선언된 PK가 포함된 경우에 작동합니다.

UPDATE
  (
    SELECT
      a.COL1, a.PKCOL
    FROM
      TABLE1 a,
      TABLE2 b
    WHERE
      a.FK = b.PK
      AND b.COL2 IN ('SET OF VALUES')
  ) update_tbl
SET
  update_tbl.COL1 = 'VALUE'

및 (b) 표 1.FK가 TABLE2에 대해 선언된 외부 키임

(선언됨은 제약 조건이 존재하고 활성화되었음을 의미합니다.)

SELECT 문을 UPDATE로 전환하는 멋지고 빠르고 일관된 방법은 ROWID를 기반으로 업데이트하는 것입니다.

UPDATE
  TABLE1
SET
  COL1 = 'VALUE'
WHERE
  ROWID in
    (
    SELECT
      a.rowid
    FROM
      TABLE1 a,
      TABLE2 b
    WHERE
      a.FK = b.PK
      AND b.COL2 IN ('SET OF VALUES')
    )

따라서 내부 쿼리는 업데이트할 행을 정의하는 것입니다.

예제의 구문은 괜찮지만 오라클의 경우 하위 쿼리에 기본 키가 포함되어 있어야 합니다.그것은 상당히 중요한 제한 사항입니다.

관련 참고로 다음과 같이 괄호를 사용하여 IN 문에서 두 개 이상의 필드를 사용할 수도 있습니다.

UPDATE
  TABLE1 update_tbl
SET
  update_tbl.COL1 = 'VALUE'
WHERE
  (update_tbl.PK1, update_tbl.pk2) in(
                      select some_field1, some_field2
                      from some_table st
                      where st.some_fields = 'some conditions'
                      );

업데이트를 수행할 때는 분명히 시스템에 값을 하나의 새 값으로 업데이트하도록 지시할 수 있습니다. 즉, "X"를 "Y"와 "Z"로 모두 업데이트하도록 지시하는 것은 의미가 없습니다.따라서 인라인 뷰의 결과를 기반으로 업데이트할 때 Oracle은 수정된 열이 두 번 업데이트되지 않도록 충분한 제약 조건이 있는지 확인합니다.

당신의 경우, 저는 표 2를 기대합니다.PK는 실제로 선언된 기본 키가 아닙니다.해당 열에 기본 또는 고유 제약 조건을 지정하면 이동할 수 있습니다.

오라클에서 내부적으로 사용하는 업데이트 가입 카디널리티 검사를 뒷받침하는 문서화되지 않은 힌트가 있지만, 사용하는 것은 권장하지 않습니다.

이에 대한 한 가지 해결 방법은 동일한 테스트 대상이 아닌 MERGE 문을 사용하는 것입니다.

여기서 필요한 을 찾았습니다. 유용한 SQL 명령입니다.

는 조인 로 한 .
의 해결책들을 했지만 성공하지 못했습니다 으)

에서 가리킨 .
을 성공적으로 할 수 .
다른 해결책이 있을거라 확신하지만 이 방법이 효과가 있었으니...

DECLARE

 /* Output variables to hold the result of the query: */
 a T1.e%TYPE;
 b T2.f%TYPE;
 c T2.g%TYPE;

 /* Cursor declaration: */
 CURSOR T1Cursor IS
   SELECT T1.e, T2.f, T2.g
   FROM T1, T2
   WHERE T1.id = T2.id AND T1.e <> T2.f

 FOR UPDATE;

BEGIN

  OPEN T1Cursor;

  LOOP

    /* Retrieve each row of the result of the above query
    into PL/SQL variables: */
    FETCH T1Cursor INTO a, b;

    /* If there are no more rows to fetch, exit the loop: */
    EXIT WHEN T1Cursor%NOTFOUND;

    /* Delete the current tuple: */
    DELETE FROM T1 WHERE CURRENT OF T1Cursor;

    /* Insert the reverse tuple: */
    INSERT INTO T1 VALUES(b, a);

    /* Here is my stuff using the variables to update my table */
    UPDATE T2
    SET T2.f = a
    WHERE T2.id = c;

  END LOOP;

  /* Free cursor used by the query. */
  CLOSE T1Cursor;

END;
.
run;


것을 잊지 마세요;-): 는것잊마지십오시을고하커참밋 ;-)

UPDATE 절의 쿼리 결과 집합에 있는 각 행은 업데이트하려는 테이블의 행 중 하나만 다시 매핑해야 하며 Oracle이 자동으로 추적할 수 있습니다.쿼리는 실제로 보기이기 때문에 Oracle이 업데이트할 행을 알기 위해 보기를 다시 대상 테이블에 결합할 수 있어야 합니다.

즉, 대상 테이블의 기본 키를 해당 쿼리에 포함해야 합니다.다른 고유 인덱스 필드도 사용할 수 있지만 Oracle DBMS가 이를 허용할 정도로 똑똑한지는 장담할 수 없습니다.

언급URL : https://stackoverflow.com/questions/230196/using-a-subquery-instead-of-a-table-name-in-an-oracle-update-statement

반응형