"ORA-01779: 비키 값 저장표에 대응하는 열을 수정할 수 없음"에 관련된 개념과 해결 방법
키 값 저장표가 무엇인지 이해하기 전에 먼저 업데이트 가능한 연결 보기라는 개념을 알아야 한다. 키 값 저장표는 업데이트를 허용하는 필드 정보를 저장하는 표일 뿐이다.왜 이런 시계가 나왔을까?한 걸음 한 걸음 봅시다.
뷰, 조인 뷰, 업데이트 가능한 조인 뷰의 개념 이해
보기는 보기 대상과 내장 보기 두 종류로 나눌 수 있다.
- 뷰 개체(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)라고 부른다.하위 질의는 다음과 같은 범주로 나눌 수 있습니다.
--
--
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
하고 다른 방식으로 판단한 후 처리UPDATE
를 MERGE
문구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.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.