이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
당신은 다음과 같은 페이지를 보고 싶을 수도 있습니다.현재버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

16.4. INSERT, UPDATE 및 DELETE에 대한 무지개 토토

16.4.1. 보기 무지개 토토과의 차이점

INSERT, UPDATE 및 DELETE에 정의된 규칙은 다음과 같습니다. 이전에 설명한 보기 규칙과 완전히 다릅니다. 섹션. 첫째, CREATE RULE 명령은 더 많은 것을 허용합니다.

  • 그들은 아무 조치도 취할 수 없습니다.

  • 그들은 여러 가지 행동을 가질 수 있습니다.

  • INSTEAD 키워드는 선택사항입니다.

  • 의사 관계 NEW 및 OLD가 유용해집니다.

  • 그들은 무지개 토토 자격을 가질 수 있습니다.

둘째, 그들은 분석 트리를 제자리에서 수정하지 않습니다. 대신 그들은 0개 또는 다수의 새로운 구문 분석 트리를 생성하고 원본.

16.4.2. 어떻게 이 무지개 토토은 작동합니다

구문을 유지하세요

CREATE RULE rule_name AS ON 이벤트
    TO 객체 [WHERE 무지개 토토_자격]
    DO [대신] [작업 | (행동) | 아무것도];

생각해 보세요. 다음에서,업데이트 무지개 토토ON INSERT, UPDATE 또는 ON에 정의된 무지개 토토을 의미합니다. 삭제합니다.

업데이트 무지개 토토은 결과가 나올 때 무지개 토토 시스템에 의해 적용됩니다. 관계 및 구문 분석 트리의 명령 유형은 CREATE RULE 명령에 제공된 개체 및 이벤트입니다. 업데이트용 무지개 토토에 따라 무지개 토토 시스템은 구문 분석 트리 목록을 생성합니다. 처음에는 구문 분석 트리 목록이 비어 있습니다. 0이 있을 수 있습니다(NOTHING 키워드), 하나 또는 여러 작업. 단순화하기 위해 우리는 한 번의 행동으로 통치하십시오. 이 무지개 토토에는 자격이 있을 수도 있고 없을 수도 있습니다. INSTEAD일 수도 있고 아닐 수도 있습니다.

무지개 토토 제한이란 무엇입니까? 제한사항을 알려주는 내용입니다 무지개 토토의 작업을 수행해야 하는 경우와 수행하지 않는 경우. 이 자격은 NEW 및/또는 OLD 의사만 참조할 수 있습니다. 기본적으로 대상으로 주어진 관계인 관계(그러나 특별한 의미로).

따라서 다음 구문 분석 트리를 생성하는 네 가지 경우가 있습니다. 단일 작업 규칙의 경우.

  • 자격이 없고 대신하지 않음:

    • 무지개 토토 작업의 구문 분석 트리 원래 구문 분석 트리의 자격이 추가되었습니다.

  • 자격은 없지만 대신:

    • 무지개 토토 작업의 구문 분석 트리 원래 구문 분석 트리의 자격이 추가되었습니다.

  • 자격이 부여되었으나 대신 제공되지 않음:

    • 무지개 토토이 실행되는 무지개 토토 작업의 구문 분석 트리 자격 및 원래 구문 분석 트리의 자격이 추가되었습니다.

  • 자격 부여 및 대신:

    • 무지개 토토이 실행되는 무지개 토토 작업의 구문 분석 트리 자격 및 원래 구문 분석 트리의 자격이 추가되었습니다.

    • 부정된 무지개 토토이 있는 원래 구문 분석 트리 자격이 추가되었습니다.

마지막으로 규칙이 INSTEAD가 아닌 경우 변경되지 않은 원본 구문 분석 트리가 목록에 추가됩니다. 대신에 자격을 갖춘 사람만이 규칙은 이미 원본 구문 분석 트리를 추가하므로 결국 다음과 같이 됩니다. 하나의 규칙에 대한 하나 또는 두 개의 출력 구문 분석 트리 행동.

ON INSERT 무지개 토토의 경우 원래 쿼리(억제되지 않은 경우) by INSTEAD)는 무지개 토토에 의해 추가된 작업보다 먼저 수행됩니다. 이 작업이 삽입된 행을 볼 수 있도록 합니다. 하지만 ON의 경우 UPDATE 및 ON DELETE 무지개 토토, 원래 쿼리는 이후에 수행됩니다. 무지개 토토에 의해 추가된 작업입니다. 이를 통해 작업이 수행될 수 있음을 보장합니다. 업데이트되거나 삭제될 행을 확인하세요. 그렇지 않으면, 작업은 일치하는 행을 찾지 못하기 때문에 아무 작업도 수행하지 않을 수 있습니다. 그들의 자격.

규칙 작업에서 생성된 구문 분석 트리는 시스템을 다시 작성하면 더 많은 규칙이 적용될 수도 있습니다. 결과적으로 더 많거나 적은 구문 분석 트리가 생성됩니다. 따라서 구문 분석 트리는 규칙 작업에는 다른 명령 유형이 있어야 합니다. 또 다른 결과 관계. 그렇지 않으면 이 재귀 프로세스는 결국 루프에 빠지게 됩니다. 컴파일된 재귀 제한이 있습니다. 현재 10회 반복. 10회 반복 후에도 여전히 남아 있는 경우 규칙 시스템을 적용하기 위한 규칙 업데이트는 루프 오버를 가정합니다. 여러 규칙을 정의하고 오류를 보고합니다.

다음 작업에서 발견된 구문 분석 트리pg_rewrite시스템 카탈로그는 템플릿일 뿐입니다. NEW 및 OLD, 일부 대체 작업을 수행해야 가능합니다. 사용. NEW에 대한 참조의 경우 원본의 대상 목록 쿼리는 해당 항목을 검색합니다. 발견되면 그 항목의 표현식이 참조를 대체합니다. 그렇지 않으면 NEW는 의미합니다. OLD(업데이트의 경우)와 동일하거나 NULL(업데이트의 경우)로 대체됩니다. 삽입). OLD에 대한 모든 참조는 OLD에 대한 참조로 대체됩니다. 결과 관계인 범위 테이블 항목입니다.

업데이트 무지개 토토 적용을 마친 후 보기 무지개 토토을 적용합니다 생성된 구문 분석 트리에. 뷰에 새 업데이트를 삽입할 수 없습니다. 작업을 수행하므로 출력에 업데이트 무지개 토토을 적용할 필요가 없습니다. 뷰 재작성.

16.4.2.1. 단계별 첫 번째 무지개 토토

우리는 sl_avail 열의 변경 사항을 추적하고 싶습니다.신발끈_데이터관계. 그래서 우리는 설정했습니다 로그 테이블과 조건부로 로그 항목을 작성하는 무지개 토토 UPDATE가 수행될 때신발끈_데이터.

CREATE TABLE 신발끈_로그(
    sl_name char(10), -- 신발끈 변경됨
    sl_avail 정수, -- 새로운 사용 가능한 값
    log_who 텍스트, -- 누가 그랬습니까?
    log_when 타임스탬프 -- 언제
);

신발끈_데이터 업데이트 시 log_shoelace 규칙 생성
    NEW.sl_avail != OLD.sl_avail 위치
    신발끈_로그 값(
                                    NEW.sl_name,
                                    NEW.sl_avail,
                                    현재_사용자,
                                    현재_타임스탬프
                                );

이제 알은 그렇습니다

al_bundy= 업데이트 신발끈_데이터 설정 sl_avail = 6                       
al_bundy- sl_name = 'sl7';

그리고 우리는 로그 테이블을 봅니다.

al_bundy= SELECT * FROM shoelace_log;
sl_name |sl_avail|log_who|log_when                        
--------+---------+---------+-------------------
sl7 |       6|Al |10월 20일 화요일 16:14:45 1998년 MET DST
(1행)

그것이 우리가 기대했던 것입니다. 백그라운드에서 무슨 일이 일어났나요? 다음입니다. 파서가 파싱 트리를 생성했습니다(이것은 원래 구문 분석 트리의 일부가 강조 표시되는 시간 작업의 기반은 업데이트를 위한 규칙 작업이기 때문입니다. 규칙).

신발끈_데이터 설정 sl_avail = 6 업데이트
  FROM 신발끈_데이터 신발끈_데이터
 WHERE bpchareq(shoelace_data.sl_name, 'sl7');

무지개 토토이 있습니다log_shoelace그것 무지개 토토 자격 표현식을 사용하여 ON UPDATE입니다.

int4ne(NEW.sl_avail, OLD.sl_avail)

그리고 하나의 작업

신발끈_로그 값에 삽입(
       *NEW*.sl_name, *NEW*.sl_avail,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*;

보통은 할 수 없기 때문에 조금 이상해 보입니다. INSERT ... VALUES ... FROM을 작성합니다. 여기서 FROM 절은 다음과 같습니다. 단지 *NEW* 및 *OLD*에 대한 구문 분석 트리입니다. 이것들은 그들이 필요하기 때문에 INSERT 명령의 변수에서 참조할 수 있습니다. 쿼리트리.

규칙은 정규화된 비INSTEAD 규칙이므로 규칙은 시스템은 두 개의 구문 분석 트리를 반환해야 합니다: 수정된 규칙 액션과 원래의 구문 분석 트리. 첫 번째 단계에서는 원래 쿼리의 범위 테이블이 규칙의 작업 구문 분석 트리. 그 결과는 다음과 같습니다.

신발끈_로그 값에 삽입(
       *NEW*.sl_name, *NEW*.sl_avail,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*,신발끈_데이터 신발끈_데이터;

2단계에서는 무지개 토토 제한이 추가되므로 결과 집합은 sl_avail이 변경되는 행으로 제한됩니다.

신발끈_로그 값에 삽입(
       *NEW*.sl_name, *NEW*.sl_avail,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*,
       신발끈_데이터 신발끈_데이터어디 int4ne(*NEW*.sl_avail, *OLD*.sl_avail);

INSERT ... VALUES 이후로 이것은 더욱 이상해 보입니다. WHERE 절도 없지만 플래너와 집행자는 그것에 어려움을 겪지 않을 것입니다. 그들은 다음을 수행해야 합니다. INSERT ... SELECT에 대해서도 이와 동일한 기능을 지원합니다. 3단계에서는 원본 구문 분석 트리의 자격이 추가됩니다. 결과 집합을 터치된 행으로만 추가로 제한 원래의 구문 분석 트리를 통해.

신발끈_로그 값에 삽입(
       *NEW*.sl_name, *NEW*.sl_avail,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*,
       신발끈_데이터 신발끈_데이터
 WHERE int4ne(*NEW*.sl_avail, *OLD*.sl_avail)AND bpchareq(신발끈_data.sl_name, 'sl7');

4단계는 새 참조를 대상 목록으로 대체합니다. 원래 구문 분석 트리의 항목 또는 일치하는 항목 결과 관계의 변수 참조.

신발끈_로그 값에 삽입(신발끈_데이터.sl_name, 6,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*,
       신발끈_데이터 신발끈_데이터
 어디에서 int4ne(6, *OLD*.sl_avail)
   AND bpchareq(신발끈_데이터.sl_name, 'sl7');

5단계에서는 OLD 참조를 결과 관계로 변경합니다. 참조.

신발끈_로그 값에 삽입(
       신발끈_데이터.sl_name, 6,
       현재_사용자, 현재_타임스탬프
  FROM 신발끈_데이터 *NEW*, 신발끈_데이터 *OLD*,
       신발끈_데이터 신발끈_데이터
 여기서 int4ne(6,신발끈_data.sl_avail)
   AND bpchareq(신발끈_데이터.sl_name, 'sl7');

그렇습니다. 규칙은 INSTEAD가 아니므로 다음도 출력합니다. 원래의 구문 분석 트리. 즉, 규칙의 출력은 시스템은 동일한 두 개의 구문 분석 트리 목록입니다. 진술:

신발끈_로그 값에 삽입(
       신발끈_데이터.sl_name, 6,
       현재_사용자, 현재_타임스탬프
  신발끈_데이터에서
 어디에 6 != shoelace_data.sl_avail
   AND 신발끈_데이터.sl_name = 'sl7';

업데이트 신발끈_데이터 SET sl_avail = 6
 sl_name = 'sl7';

이것들은 이 순서대로 실행되며 그게 바로 규칙이 정의합니다. 교체 및 자격 원래 쿼리가 다음과 같은지 확인합니다.

신발끈_데이터 설정 sl_color = '녹색' 업데이트
 sl_name = 'sl7';

로그 항목이 기록되지 않습니다. 이번에는 원본 구문 분석 트리에 sl_avail에 대한 대상 목록 항목이 포함되어 있지 않습니다. 따라서 NEW.sl_avail은 shoelace_data.sl_avail로 대체됩니다. 추가 쿼리가 발생함

신발끈_로그 값에 삽입(
       신발끈_데이터.sl_name,신발끈_data.sl_avail,
       현재_사용자, 현재_타임스탬프)
  신발끈_데이터에서
 어디서신발끈_data.sl_avail!= shoelace_data.sl_avail
   AND 신발끈_데이터.sl_name = 'sl7';

그리고 그 자격은 결코 사실이 아닐 것입니다. 그것은 또한 원래 쿼리가 여러 행을 수정하는 경우 작동합니다. 그렇다면 알 명령을 내릴 것입니다.

신발끈_데이터 설정 sl_avail = 0 업데이트
 sl_color = '검은색';

실제로 4개의 행이 업데이트됩니다(sl1, sl2, sl3 및 sl4). 하지만 sl3에는 이미 sl_avail = 0이 있습니다. 이번에는 원래 구문 분석 나무의 자격은 다르며 그 결과 추가 구문 분석 트리

신발끈_로그에 삽입 선택
       신발끈_데이터.sl_name, 0,
       현재_사용자, 현재_타임스탬프
  신발끈_데이터에서
 어디에 0 != shoelace_data.sl_avail
   그리고신발끈_data.sl_color = '검은색';

이 분석 트리는 반드시 세 개의 새로운 로그 항목을 삽입할 것입니다. 그리고 그것은 절대적으로 정확합니다.

여기서 우리는 원본이 왜 중요한지 알 수 있습니다. 구문 분석 트리가 마지막으로 실행됩니다. 업데이트가 먼저 실행되면 모든 행이 이미 0으로 설정되어 있으므로 INSERT 로깅은 0 !=인 행을 찾지 못합니다. 신발끈_데이터.sl_avail.

16.4.3. 뷰와의 협력

언급된 항목으로부터 뷰 관계를 보호하는 간단한 방법 누군가가 INSERT, UPDATE 및 DELETE를 시도할 가능성 그 이유는 해당 구문 분석 트리가 버려지도록 하는 것입니다. 우리는 창조한다 무지개 토토

신발에 삽입할 때 shoe_ins_protect 무지개 토토 생성
    대신 아무것도 하지 마십시오.
신발 업데이트 시 shoe_upd_protect 무지개 토토 생성
    대신 아무것도 하지 마십시오.
신발 삭제 시 shoe_del_protect 무지개 토토 생성
    대신 아무것도 하지 마십시오.

Al이 이제 뷰에서 이러한 작업을 수행하려고 시도하면 관계신발, 무지개 토토 시스템은 무지개 토토을 적용합니다. 무지개 토토에는 작업이 없고 대신, 결과 구문 분석 트리 목록은 비어 있고 아무것도 없기 때문에 전체 쿼리는 아무것도 되지 않습니다. 무지개 토토 시스템이 완료된 후 최적화되거나 실행되도록 남겨두었습니다. 그것으로.

참고:이렇게 하면 프런트엔드가 짜증날 수 있습니다 전혀 아무 일도 일어나지 않았기 때문에 응용 프로그램 데이터베이스이므로 백엔드는 다음에 대해 아무것도 반환하지 않습니다. 쿼리. 심지어 aPGRES_EMPTY_QUERY다음에서 사용 가능libpq. 에서psql, 아무 일도 일어나지 않습니다. 이것은 아마도 앞으로는 바뀔 것이다.

규칙 시스템을 사용하는 보다 정교한 방법은 다음을 생성하는 것입니다. 구문 분석 트리를 올바른 작업을 수행하는 트리로 다시 작성하는 규칙 실제 테이블에서의 작업. 그렇게 하려면신발끈view, 우리는 다음을 생성합니다 규칙:

신발끈에 삽입할 때와 같이 신발끈_인 규칙을 생성하세요.
    대신에
    신발끈_데이터 값에 삽입(
           NEW.sl_name,
           NEW.sl_avail,
           NEW.sl_color,
           NEW.sl_len,
           NEW.sl_unit);

신발끈 업데이트 시 규칙 shoelace_upd 생성
    대신에
    신발끈_데이터 세트 업데이트
           sl_name = NEW.sl_name,
           sl_avail = NEW.sl_avail,
           sl_color = NEW.sl_color,
           sl_len = NEW.sl_len,
           sl_unit = NEW.sl_unit
     sl_name = OLD.sl_name은 어디에 있습니까?

신발끈 삭제 시 규칙 shoelace_del 생성
    대신에
    신발끈_데이터에서 삭제
     sl_name = OLD.sl_name;

이제 알의 가게에 신발끈 한 뭉치가 도착하고 그것은 큰 부품 목록을 가지고 있습니다. 알은 계산을 잘 못하는데, 그래서 우리는 그가 신발끈 보기를 수동으로 업데이트하는 것을 원하지 않습니다. 대신에 우리는 두 개의 작은 테이블을 설치했는데, 그 중 하나는 그가 테이블을 삽입할 수 있는 곳이었습니다. 부품 목록의 항목과 특별한 트릭이 있는 항목. 는 이에 대한 생성 명령은 다음과 같습니다.

CREATE TABLE 신발끈_도착(
    arr_name 문자(10),
    arr_퀀트 정수
);

CREATE TABLE 신발끈_확인(
    ok_name 문자(10),
    ok_Quant 정수
);

shoelace_ok에 삽입할 때와 마찬가지로 shoelace_ok_ins 규칙을 생성합니다.
    대신에
    UPDATE 신발끈 세트
           sl_avail = sl_avail + NEW.ok_Quant
     sl_name = NEW.ok_name;

이제 알은 앉아서 무엇이든 할 수 있습니다.

al_bundy= SELECT * FROM shoelace_arrive;
arr_name |arr_Quant
----------+---------
sl3 |       10
sl6 |       20
sl8 |       20
(3행)

정확히 부품 목록에 있는 내용입니다. 우리는 간단히 살펴 봅니다. 현재 데이터,

al_bundy= SELECT * FROM 신발끈;
sl_name |sl_avail|sl_color |sl_len|sl_unit |sl_len_cm
----------+---------+----------+------+---------+---------
sl1 |       5|검은색 |    80|cm |       80
sl2 |       6|검은색 |   100|cm |      100
sl7 |       6|갈색 |    60|cm |       60
sl3 |       0|검은색 |    35|인치 |     88.9
sl4 |       8|검은색 |    40|인치 |    101.6
sl8 |       1|갈색 |    40|인치 |    101.6
sl5 |       4|갈색 |     1|분 |      100
sl6 |       0|갈색 |   0.9|분 |       90
(8행)

도착된 신발끈을 안으로 넣으세요

al_bundy= 신발끈_ok에 삽입 SELECT * FROM 신발끈_arrive;

그리고 결과를 확인하세요

al_bundy= SELECT * 신발끈에서 ORDER BY sl_name;
sl_name |sl_avail|sl_color |sl_len|sl_unit |sl_len_cm
----------+---------+----------+------+---------+---------
sl1 |       5|검은색 |    80|cm |       80
sl2 |       6|검은색 |   100|cm |      100
sl7 |       6|갈색 |    60|cm |       60
sl4 |       8|검은색 |    40|인치 |    101.6
sl3 |      10|검은색 |    35|인치 |     88.9
sl8 |      21|브라운 |    40|인치 |    101.6
sl5 |       4|갈색 |     1|분 |      100
sl6 |      20|갈색 |   0.9|분 |       90
(8열)

al_bundy= SELECT * 신발끈_로그에서;
sl_name |sl_avail|log_who|log_when                        
--------+---------+---------+-------------------
sl7 |       6|Al |10월 20일 화요일 19:14:45 1998년 MET DST
sl3 |      10|Al |10월 20일 화요일 19:25:16 1998년 MET DST
sl6 |      20|Al |10월 20일 화요일 19:25:16 1998년 MET DST
sl8 |      21|Al |10월 20일 화요일 19:25:16 1998년 MET DST
(4행)

INSERT ... SELECT에서 이것들까지 먼 길이 있습니다 결과. 그리고 이에 대한 설명은 이 문서의 마지막이 될 것입니다 (그러나 마지막 예는 아닙니다 :-). 먼저 파서(parser)가 있었습니다. 출력

신발끈에 삽입_ok 선택
       신발끈_도착.arr_name, 신발끈_도착.arr_Quant
  FROM 신발끈_도착 신발끈_도착, 신발끈_확인 신발끈_확인;

이제 첫 번째 무지개 토토신발끈_ok_ins적용되어 다음으로 바뀐다

신발끈 세트 업데이트
       sl_avail = int4pl(shoelace.sl_avail, shoelace_arrive.arr_Quant)
  FROM 신발끈_도착 신발끈_도착, 신발끈_확인 신발끈_확인,
       신발끈_확인 *오래됨*, 신발끈_확인 *신규*,
       신발끈 신발끈
 WHERE bpchareq(신발끈.sl_name, showlace_arrive.arr_name);

그리고 원래 INSERT를 버립니다신발끈_ok. 이 다시 작성된 쿼리는 다음으로 전달됩니다. 규칙 시스템을 다시 적용하고 두 번째로 적용된 규칙신발끈_upd생산됨

신발끈_데이터 세트 업데이트
       sl_name = 신발끈.sl_name,
       sl_avail = int4pl(shoelace.sl_avail, shoelace_arrive.arr_Quant),
       sl_color = 신발끈.sl_color,
       sl_len = 신발끈.sl_len,
       sl_unit = 신발끈.sl_unit
  FROM 신발끈_도착 신발끈_도착, 신발끈_확인 신발끈_확인,
       신발끈_확인 *오래됨*, 신발끈_확인 *신규*,
       신발끈 신발끈, 신발끈 *OLD*,
       신발끈 *NEW*, 신발끈_데이터 showlace_data
 WHERE bpchareq(shoelace.sl_name, showlace_arrive.arr_name)
   AND bpchareq(신발끈_데이터.sl_name, 신발끈.sl_name);

다시 말하지만 이것은 INSTEAD 규칙이고 이전 구문 분석 트리는 다음과 같습니다. 쓰레기. 이 쿼리는 여전히 뷰를 사용합니다.신발끈. 하지만 무지개 토토 시스템은 완성되지 않았습니다 이 루프를 사용하면 무지개 토토이 계속 적용됩니다._RET신발끈그럼 우리는 얻는다

신발끈_데이터 세트 업데이트
       sl_name = s.sl_name,
       sl_avail = int4pl(s.sl_avail, 신발끈_arrive.arr_Quant),
       sl_color = s.sl_color,
       sl_len = s.sl_len,
       sl_unit = s.sl_unit
  FROM 신발끈_도착 신발끈_도착, 신발끈_확인 신발끈_확인,
       신발끈_확인 *오래됨*, 신발끈_확인 *신규*,
       신발끈 신발끈, 신발끈 *OLD*,
       신발끈 *NEW*, 신발끈_데이터 showlace_data,
       신발끈 *오래된*, 신발끈 *새상품*,
       신발끈_데이터 s, 단위 u
 어디에서 bpchareq(s.sl_name, showlace_arrive.arr_name)
   AND bpchareq(신발끈_데이터.sl_name, s.sl_name);

다시 업데이트 무지개 토토이 적용되어 바퀴가 회전합니다 계속해서 3번째 재작성 단계에 있습니다. 이 시간 무지개 토토log_shoelace생성되는 것이 적용됩니다. 추가 구문 분석 트리

신발끈_로그에 삽입 선택
       s.sl_이름,
       int4pl(s.sl_avail, 신발끈_arrive.arr_Quant),
       현재_사용자,
       현재_타임스탬프
  FROM 신발끈_도착 신발끈_도착, 신발끈_확인 신발끈_확인,
       신발끈_확인 *오래됨*, 신발끈_확인 *신규*,
       신발끈 신발끈, 신발끈 *OLD*,
       신발끈 *NEW*, 신발끈_데이터 showlace_data,
       신발끈 *오래된*, 신발끈 *새상품*,
       신발끈_데이터 s, 단위 u,
       신발끈_데이터 *이전*, 신발끈_데이터 *신규*
       신발끈_로그 신발끈_로그
 어디에서 bpchareq(s.sl_name, showlace_arrive.arr_name)
   AND bpchareq(신발끈_데이터.sl_name, s.sl_name);
   AND int4ne(int4pl(s.sl_avail, 신발끈_arrive.arr_Quant), s.sl_avail);

그 후 규칙 시스템은 규칙이 부족하고 다음을 반환합니다. 생성된 구문 분석 트리. 그래서 우리는 두 개의 최종 구문 분석 트리로 끝납니다. 이는SQL문장

신발끈_로그에 삽입 선택
       s.sl_이름,
       s.sl_avail + 신발끈_도착.arr_Quant,
       현재_사용자,
       현재_타임스탬프
  FROM 신발끈_도착 신발끈_도착, 신발끈_데이터 신발끈_데이터,
       신발끈_데이터
 어디서 s.sl_name = 신발끈_arrive.arr_name
   AND 신발끈_데이터.sl_name = s.sl_name
   AND s.sl_avail + 신발끈_arrive.arr_Quant != s.sl_avail;

신발끈_데이터 세트 업데이트
       sl_avail = 신발끈_data.sl_avail + 신발끈_arrive.arr_Quant
  FROM 신발끈_도착 신발끈_도착,
       신발끈_데이터 신발끈_데이터,
       신발끈_데이터
 WHERE s.sl_name = 신발끈_arrive.sl_name
   AND 신발끈_데이터.sl_name = s.sl_name;

결과적으로 하나의 관계에서 오는 데이터가 삽입되었습니다. 다른 것으로, 세 번째 업데이트로 변경, 다음으로 변경 네 번째 업데이트와 다섯 번째 업데이트의 최종 업데이트 기록 두 개의 쿼리로 축소됩니다.

약간 보기 흉한 세부 사항이 있습니다. 을 보면서 두 가지 쿼리가 밝혀졌습니다.신발끈_데이터관계가 확실히 하나로 줄일 수 있는 범위 테이블입니다. 는 플래너가 이를 처리하지 않으므로 실행 계획은 INSERT의 규칙 시스템 출력은 다음과 같습니다.

중첩 루프
  - 병합 조인
        - 서열 스캔
              - 정렬
                    - s의 서열 스캔
        - 서열 스캔
              - 정렬
                    - 신발끈_도착 시 서열 스캔
  - 신발끈_데이터의 서열 스캔

추가 범위 테이블 항목을 생략하면 다음과 같은 결과가 발생합니다. 에

병합 조인
  - 서열 스캔
        - 정렬
              - s의 서열 스캔
  - 서열 스캔
        - 정렬
              - 신발끈의 서열 스캔_도착

로그 관계에서 완전히 동일한 항목을 생성합니다. 따라서 규칙 시스템은 다음에서 한 번의 추가 검사를 발생시켰습니다.신발끈_데이터절대 그렇지 않은 관계 필요합니다. 그리고 동일한 사용되지 않는 검색이 다음에서 다시 한 번 수행됩니다. 업데이트. 그런데 그걸 가능하게 만드는 게 정말 힘든 일이었어요. 전혀.

최종 시연포스트그레SQL규칙 시스템과 그 힘. 신발끈을 파는 귀여운 금발녀가 있어요. 그리고 Al이 할 수 있는 일 그녀는 귀여울 뿐만 아니라 똑똑하기도 합니다. 너무 똑똑해요. 따라서 때때로 Al이 주문하는 일이 발생합니다. 절대 팔 수 없는 신발끈. 이번에 그는 마젠타색 신발끈 1000켤레를 주문했고 이후 다른 종류도 주문했습니다 현재는 사용할 수 없지만 그는 일부를 구매하기로 약속했습니다. 또한 핑크색 데이터베이스에 대한 데이터베이스도 준비했습니다.

al_bundy= 신발끈 값에 삽입 
al_bundy- ('sl9', 0, '핑크', 35.0, '인치', 0.0);
al_bundy= 신발끈 값에 삽입 
al_bundy- ('sl10', 1000, '마젠타', 40.0, '인치', 0.0);

이런 일이 자주 발생하기 때문에 신발끈을 찾아야 합니다 때로는 신발이 전혀 맞지 않는 항목입니다. 우리는 할 수 있었다 매번 복잡한 설명을 사용하거나 그것을 위해 보기. 이에 대한 견해는 다음과 같습니다

CREATE VIEW 신발끈_구식 AS 보기
    SELECT * 존재하지 않는 신발끈에서
        (slcolor = sl_color인 신발에서 신발 이름 선택);

그 출력은 다음과 같습니다

al_bundy= SELECT * FROM 신발끈_구식;
sl_name |sl_avail|sl_color |sl_len|sl_unit |sl_len_cm
----------+---------+----------+------+---------+---------
sl9 |       0|핑크 |    35|인치 |     88.9
sl10 |    1000|자홍색 |    40|인치 |    101.6

1000개의 자홍색 신발끈을 얻으려면 Al에게 빚을 져야 합니다. 그것들을 버리면 또 다른 문제가 됩니다. 핑크색 입구 우리는 삭제. 조금 더 어렵게 만들기 위해포스트그레SQL, 직접 삭제하지는 않습니다. 대신 뷰를 하나 더 만듭니다.

CREATE VIEW shoelace_candelete AS 보기
    SELECT * FROM shoelace_obsolete WHERE sl_avail = 0;

이렇게 하세요:

존재하는 신발끈에서 삭제
    (SELECT * FROM shoelace_candelete
             sl_name = 신발끈.sl_name);

짜잔아:

al_bundy= SELECT * FROM 신발끈;
sl_name |sl_avail|sl_color |sl_len|sl_unit |sl_len_cm
----------+---------+----------+------+---------+---------
sl1 |       5|검은색 |    80|cm |       80
sl2 |       6|검은색 |   100|cm |      100
sl7 |       6|갈색 |    60|cm |       60
sl4 |       8|검은색 |    40|인치 |    101.6
sl3 |      10|검은색 |    35|인치 |     88.9
sl8 |      21|브라운 |    40|인치 |    101.6
sl10 |    1000|자홍색 |    40|인치 |    101.6
sl5 |       4|갈색 |     1|분 |      100
sl6 |      20|갈색 |   0.9|분 |       90
(9행)

다음에 있는 하위 선택 제한을 사용하여 보기에 대한 삭제 총 4개의 중첩/결합된 뷰를 사용하며 그 중 하나는 자체적으로 뷰와 위치를 포함하는 하위 선택 자격 계산된 뷰 열이 사용되며 하나로 다시 작성됩니다. 실제 데이터에서 요청된 데이터를 삭제하는 단일 구문 분석 트리 테이블.

실제로는 몇 가지 상황만 있다고 생각합니다. 그러한 구조가 필요한 세상. 하지만 그것은 나를 만든다 효과가 있어서 편해요.

진실은:이것을 하다가 버그를 하나 더 발견했습니다 이 문서를 작성 중입니다. 하지만 그걸 고친 후에 나는 조금 전혀 작동한다는 사실에 놀랐습니다.