CREATE RULE — 새 룰 정의
CREATE [ OR REPLACE ] RULE이름
AS ON이벤트
TO테이블이름
[ WHERE조건
] DO [ ALSO | INSTEAD ] { NOTHING |명령
| (명령
;명령
... ) }이벤트
자리에는: SELECT | INSERT | UPDATE | DELETE
CREATE RULE
명령은 해당 테이블이나 뷰에 새
룰을 추가한다.
CREATE OR REPLACE RULE
명령은 같은 이름의
해당 룰이 있으면 바꾸고 그렇지 않으면 새로 추가한다.
PostgreSQL 룰 시스템은
데이터베이스 내 테이블 대상으로 수행되는
자료 추가, 변경, 삭제 작업에 대해서 대체 작업을 수행할 수 있게 한다.
간단히 이야기하면, 이런 자료 조작 작업이 있을 때,
추가로 다른 작업을 함께 할 수 있게 한다. 또한 다른 한편으로
INSTEAD
옵션을 사용한다면, 아에 그 원래 작업을
진행하지 않고 지정한 작업을 진행하거나, 아무런 작업도 안하게
할 수도 있다. 룰은 SQL 뷰를 구현하는 도구로 사용된다.
룰은 일종의 명령 변환 메카니즘이거나, 명령 메크로로 이해해야 한다.
이 변환은 해당 명령이 실행 되기 이전에 일어남을 기억해야 한다.
작업 대상 각 개별 로우를 대상으로 추가 작업이 필요한 경우는
룰 대신에 트리거를 쓰는 것이 더 좋다.
룰에 대한 더 많은 정보는 40장에 있다.
현재, ON SELECT
룰은
INSTEAD
룰이어야 하며, 대신 실행될 명령은
단일 SELECT
명령이어야 한다.
즉, ON SELECT
룰은
테이블을 뷰로 바꾸는 역할을 한다.
이 뷰는 테이블에 저장된 자료를 보여주는 것이 아니라,
이 룰에서 지정한 명령의 결과를 보여주는 것이 된다.
하지만, ON SELECT
룰을 만들기보다
이미 CREATE VIEW
명령을 제공하고
있기 때문에, 이 명령을 이용하는 것이 더 낫다.
이 룰은 특정 뷰를 마치 테이블인 마냥 쓸 수 있도록
ON INSERT
, ON UPDATE
,
ON DELETE
룰을 그 뷰에 추가해서
자료를 조작할 수도 있다. 또한
INSERT RETURNING
작업도 룰로 구현할 수 있는데,
이 때는 RETURNING
부분의 결과를
직접 지정해야 한다.
복잡한 뷰 갱신 작업으로 조건절 있는 룰을 사용하려면,
먼저, 그 뷰에 각 작업에 대한
조건절 없는 INSTEAD
룰을 각각
만들어야 한다는 것을 알고 있어야 한다.
조건절 있는 룰이거나, INSTEAD
룰이 아니면,
update 작업을 정상적으로 진행하지 않는다.
왜냐하면, 서버는
몇몇 경우에 이런 작업은 그 뷰의 dummy 테이블에 대한 작업이
마지막으로 수행될 것이라고 판단해서 실행 금지하기 때문이다.
(원문: it thinks it might
end up trying to perform the action on the dummy table of the view
in some cases.)
조건절 있는 룰을 사용하는 경우라면,
먼저 조건절 없는 DO
INSTEAD NOTHING
룰을 만들어서,
서버가 더미 테이블 관련 작업을 아에 할 수 없도록 하는 것이
중요하다. 이렇게 하면, 조건절에 적용 되지 않는 자료들에 대해서는
INSTEAD NOTHING
작업을 하게 된다.
(현재, 이 방법은 RETURNING
쿼리를 지원하지 않는다.)
단순한 뷰인 경우는 이미 기본적으로 자료 갱신 작업을 허용하고 있다. (CREATE VIEW 명령 설명서 참조) 그래서, 굳이 사용자가 이 작업을 위해 룰을 만들 필요는 없다. 당연히 성능도 내장 자동 갱신 기능이 더 우수하다.
또 하나, 룰을 쓰는 자리에,
INSTEAD OF
트리거를 대신 쓰는 것도 고려해볼만 하다(CREATE TRIGGER 명령 설명서 참조).
이름
새로 만들 룰 이름. 이 이름은 해당 테이블 대상으로 유일해야 한다. 동일 테이블 동일 이벤트에 여러 룰이 있다면, 그 룰은 알파벳 순으로 사용된다.
이벤트
SELECT
,
INSERT
, UPDATE
, 또는
DELETE
.
INSERT
또는 UPDATE
룰을 사용하고 있는 테이블 대상으로는
INSERT ... ON CONFLICT
쿼리는 사용할 수 없다.
대신에 업데이트 가능한 뷰 사용을 고려해 볼 수 있다.
테이블이름
대상 테이블 또는 뷰 이름(스키마 이름 포함).
조건
SQL 구문으로 작성된 표현식( 결과는
boolean
형). 이 식에서는
NEW
, OLD
변수를 사용할 수 없으며,
집계 함수도 사용할 수 없다.
INSTEAD
INSTEAD
명령을 사용할 때.
원래 쿼리 대신에 여기서 지정한 명령을 대신 실행함.
ALSO
ALSO
원래 쿼리 다음에 추가로
지정한 명령을 더 실행함.
ALSO
, INSTEAD
둘 다 지정하지
않았다면, ALSO
로 간주한다.
명령
룰 실 작업 명령. 이 명령으로
SELECT
,
INSERT
, UPDATE
,
DELETE
, 또는 NOTIFY
명령을
사용할 수 있다.
조건
과
명령
안에서는
NEW
, OLD
이름의 미리
예약된 테이블을 이름을 사용할 수 있다.
NEW
는 ON INSERT
또는
ON UPDATE
룰에 사용하는 신규 자료의 로우를 뜻하며,
OLD
는 ON UPDATE
또는
ON DELETE
룰에 사용하는 옛날 자료의 로우를 뜻한다.
테이블 소유주가 그 테이블에 새 룰을 추가하거나 변경 할 수 있다.
뷰에 INSERT
, UPDATE
, 또는
DELETE
룰이 있는 경우,
뷰 칼럼을 보기 위해 RETURNING
구문을 사용할 수 있다.
이런 경우는 각각 INSERT RETURNING
,
UPDATE RETURNING
, 또는 DELETE RETURNING
명령이 그 출력을 위해 사용된다.
뷰 변경 작업에서 RETURNING
을 사용하지 않았다면,
그런데, 룰 명령으로 이 RETURNING
절은 무시된다.
현재 INSTEAD
룰에서만
RETURNING
절을 사용할 수 있다.
게다가, 이 RETURNING
절은 동일 이벤트에 대한 여러개의
룰이 있는 경우, 최종 하나에만 지정해야한다.
이 RETURNING
절이 하나도 없다면, 뷰 조작 쿼리에서
RETURNING
을 사용하면 그 쿼리는 실행되지 않는다.
룰을 사용할 때는
순환하는 룰 사용을 하고 있지는 않는지 꼭 확인이 필요하다.
예를 들어, 두 개의 룰이 각각 서로 사용하도록 지정한 경우다.
다음과 같은 경우, SELECT
명령을 실행할 때
오류가 발생한다:
CREATE RULE "_RETURN" AS ON SELECT TO t1 DO INSTEAD SELECT * FROM t2; CREATE RULE "_RETURN" AS ON SELECT TO t2 DO INSTEAD SELECT * FROM t1; SELECT * FROM t1;
현재, 룰에서 실행할 명령으로
NOTIFY
명령을 사용할 있다.
이 경우 NOTIFY
명령은 조건에 상관 없이
실행된다. 예를 들어:
CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable; UPDATE mytable SET name = 'foo' WHERE id = 42;
이 경우 id = 42
조건에 맞는 자료가 없어도
NOTIFY
명령은 실행된다.
이 특성은 다음 버전에서는 그 대상 자료가 있는 경우만
실행되도록 변경되어야 할 것이다.
CREATE RULE
구문은
PostgreSQL 확장 기능이다.