"ORA-01779: 비키 값 저장표에 대응하는 열을 수정할 수 없음"에 관련된 개념과 해결 방법

5699 단어
키 값 저장 테이블(Key-Preserved Table)은 무엇입니까?
키 값 저장표가 무엇인지 이해하기 전에 먼저 업데이트 가능한 연결 보기라는 개념을 알아야 한다. 키 값 저장표는 업데이트를 허용하는 필드 정보를 저장하는 표일 뿐이다.왜 이런 시계가 나왔을까?한 걸음 한 걸음 봅시다.

뷰, 조인 뷰, 업데이트 가능한 조인 뷰의 개념 이해


보기는 보기 대상과 내장 보기 두 종류로 나눌 수 있다.
- 뷰 개체(View Object) 데이터베이스에 있는 뷰 개체는 테이블이나 색인 등과 마찬가지로 데이터베이스 개체 중 하나이며, 테이블에 있는 원본 데이터를 기반으로 한 조회를 가상 레이어로 만든 후 외부 조회에 제공하는 개체입니다.그 본질은 조회의 실제 결과를 저장하지 않고 데이터베이스에 조회 문구만 저장하는 것이다. 사용자가 특정한 보기를 조회할 때 이 보기의 문구를 찾아 실행할 것이다.연결 보기는 한 보기에서 두 표를 연결하는 것이다.
--  SCOTT 
CREATE TABLE EMP_T AS
     SELECT *
     FROM EMP;

CREATE TABLE DEPT_T AS
     SELECT *
     FROM DEPT;

--  ( )
CREATE OR REPLACE VIEW EMP_DEPT_V
     AS
          SELECT E.EMPNO
               , E.ENAME
               , E.SAL
               , E.DEPTNO
               , D.DNAME
          FROM EMP_T E, DEPT_T D
          WHERE E.DEPTNO = D.DEPTNO;
 

- 인라인 뷰(Inline View)는 SQL 문장에 중첩된 문장을 많이 쓸 수 있다. 예를 들어 FROM 뒤에 다른 문장을 중첩할 수 있다. WHERE, SELECT, UPDATE, INSERT, DELETE 뒤에 모두 쓸 수 있다.다만 쓰는 위치가 다르고 실행하는 방식과 처리할 때의 제한이 다르다. 이런 SQL에 끼워 넣은 SQL을 서브쿼리(Subquery)라고 부른다.하위 질의는 다음과 같은 범주로 나눌 수 있습니다.
  • 내장 보기: FROM 문장에 위치하고 예처리 결과 집합의 개념
  • 에 해당한다.
  • 스칼라 서브쿼리(Scalar Subquery): 결과 값 하나만 반환하는 서브쿼리입니다.SELECT 문장에 있는 하위 조회는 하나의 값만 반환할 수 있기 때문에 반드시 양자 조회이고 WHERE 문장에도 이러한 하위 조회가 나타난다
  • 관련 하위 조회: 조회의 결과를 하위 조회에 매개 변수로 전달하는 형식
  • 일반 하위 조회: 특수한 형식의 하위 조회를 제외한 일반 용법
  • --  
    --  
    SELECT *
    FROM
         (SELECT E.EMPNO
               , E.ENAME
               , E.SAL
               , E.DEPTNO
               , D.DNAME
          FROM EMP_T E, DEPT_T D
          WHERE E.DEPTNO = D.DEPTNO
         );
    

    조인 뷰를 업데이트할 수 있는 것은 무엇입니까?
    간단합니다. UPADTE 문장에 연결 보기 (보기 대상과 내장 보기 포함) 를 넣는 문법입니다.
    SQL 문의 의미는 잠시 고려하지 않고 테스트용
    --  
    UPDATE EMP_DEPT_V
    SET ENAME = ENAME || '-' || DEPTNO;
    
    --  
    UPDATE
         (SELECT E.EMPNO
               , E.ENAME
               , E.SAL
               , E.DEPTNO
               , D.DNAME
          FROM EMP_T E, DEPT_T D
          WHERE E.DEPTNO = D.DEPTNO
         )
    SET ENAME = ENAME || '-' || DEPTNO;
    

    한 걸음 한 걸음 내려올 때, 이 문장을 집행하지 말고, 먼저 이 두 문장의 집행 결과가 무엇인지 알아맞혀 보세요.

    오보의 원리를 이해하다


    정상적인 조인 논리에 따라 DEPTT 및 EMPT 간의 관계는 일대다 관계이다. 즉, 한 부서는 여러 직원을 대응할 수 있고 한 직원은 한 번에 한 부서에 속할 수 있다.
    --  EMP_T 
    EMPNO | ENAME | DEPTNO
    7839  , KING   , 10
    7935  , MILLER , 10
    
    --  DEPT_T 
    DEPTNO | DNAME
    10     , ACCOUNTING
    

    이때 만약 두 테이블이 연결된 후, DNAME로 EMP 를 대체합니다T에서 DEPTNO면 DEPTNO의 값이 ACCOUNTING으로 바뀌는 게 뻔해요.
    EMPNO | ENAME | DEPTNO | DNAME
    7839  , KING   , 10    , ACCOUNTING
    7935  , MILLER , 10    , ACCOUNTING
    

    하지만 DEPTDEPTNO가 10인 데이터가 두 개나 있나요?
    --  DEPT_T 
    DEPTNO | DNAME
    10     , ACCOUNTING
    10     , MARCKEING
    

    연결의 결과는 다음과 같다.
    EMPNO | ENAME | DEPTNO | DNAME
    7839  , KING   , 10    , ACCOUNTING
    7839  , KING   , 10    , MARCKEING
    7935  , MILLER , 10    , ACCOUNTING
    7935  , MILLER , 10    , MARCKEING
    

    그럼 10번 부서의 값은 도대체 어느 것으로 바꿔야 합니까?그래서 이럴 때 데이터베이스도 어떻게 처리해야 할지 몰라서 ORA-01779: 의 오류만 보고할 수 있다.
    그러면 어떻게 해야만 이 키 값 저장표를 볼 수 있습니까?ORACLE은 뷰를 제공합니다.
    SELECT *
    FROM DBA_UPDATABLE_COLUMNS
    WHERE OWNER = 'SCOTT' AND TABLE_NAME = 'EMP_DEPT_V';
    
    OWNER | TABLE_NAME | COLUMN_NAME | UPDATABLE | INSERTABLE | DELETABLE
    SCOTT   EMP_DEPT_V     EMPNO            NO          NO          NO
    SCOTT   EMP_DEPT_V     ENAME            NO          NO          NO
    SCOTT   EMP_DEPT_V     SAL              NO          NO          NO
    SCOTT   EMP_DEPT_V     DEPTNO           NO          NO          NO
    SCOTT   EMP_DEPT_V     DNAME            NO          NO          NO
    
    

    이 안에서 보기EMP_DEPT_V의 필드를 변경할 수 없습니다.
    그럼 어떻게 하면 바꿀 수 있을까요?앞에서 말한 바와 같이 DEPT 를 보증할 수 있다면T표의 데이터는 유일하게 업데이트할 수 있습니다.그러니까 DEPT에서...T표에 또는 를 추가합니다.제약을 하지 않으면 데이터베이스가 유일한지 판단할 수 없기 때문에 제약을 더하면 데이터베이스에'안심하고 고쳐라. 틀리지 않을 거야!'라고 알려주는 것이다.
    ALTER TABLE DEPT_T
         ADD CONSTRAINT PK_DEPT_T PRIMARY KEY (DEPTNO);
    

    이전 테이블을 다시 한 번 보십시오. (결과가 아래와 다르면 보기를 재구성하십시오.)
    SELECT *
    FROM DBA_UPDATABLE_COLUMNS
    WHERE OWNER = 'SCOTT' AND TABLE_NAME = 'EMP_DEPT_V';
    
    OWNER | TABLE_NAME | COLUMN_NAME | UPDATABLE | INSERTABLE | DELETABLE
    SCOTT   EMP_DEPT_V     EMPNO            YES         YES         YES
    SCOTT   EMP_DEPT_V     ENAME            YES         YES         YES
    SCOTT   EMP_DEPT_V     SAL              YES         YES         YES
    SCOTT   EMP_DEPT_V     DEPTNO           YES         YES         YES
    SCOTT   EMP_DEPT_V     DNAME             NO          NO          NO
    

    이때 보실 수 있습니다. 뷰에서 EMPT표의 원래 필드는 모두 업데이트할 수 있습니다.
    앞의 문장을 집행하고 테스트해 볼 수 있다.
    총괄적으로 말하자면 연결 보기를 변경할 때 수정된 값이 유일하다는 것을 보증해야 한다. 그리고 이 사실을 데이터베이스에 알려야 한다. 데이터베이스에 알려주는 방법은 키 제약이나 유일한 제약을 구축하는 것이다.
    그렇다면 제약을 넣지 않고 변경할 수 있는 방법은 무엇일까?모든 시계가 이런 제약을 마음대로 만들 수 있는 것은 아니다.
    해결 방법:
  • 추가 /*+ BYPASS_UJVC */ 프롬프트, ORACLE에서 검사 건너뛰기(11g R2 이후 유효하지 않음, 권장하지 않음)
  • 문장을 개작UPDATE하고 다른 방식으로 판단한 후 처리
  • UPDATEMERGE문구
  • 로 바꾸다

    ORACLE 공식 문서의 설명을 참조하십시오.


    The concept of a key-preserved table is fundamental to understanding the restrictions on modifying join views. A table is key-preserved if every key of the table can also be a key of the result of the join. So, a key-preserved table has its keys preserved through a join.
    An updatable join view (also referred to as a modifiable join view) is a view that contains multiple tables in the top-level FROM clause of the SELECT statement, and is not restricted by the WITH READ ONLY clause.

    좋은 웹페이지 즐겨찾기