database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 7303 게시물 읽기
No. 7303
view 에서 rule적용 질문 (update, insert, delete)
작성자
전홍준(noidda)
작성일
2008-01-11 11:25
조회수
6,625

view에서 rule을 어떻게 적어야 할 지 몰라서 질문 올립니다.



테이블 상황은 아래와 같은 3 테이블 입니다.



CREATE TABLE tblproduct

(

  productname text,

  color integer NOT NULL,

  size integer NOT NULL,

  CONSTRAINT tblproduct_color_fkey FOREIGN KEY (color)

      REFERENCES tblcolor (colorcode) MATCH SIMPLE

      ON UPDATE NO ACTION ON DELETE NO ACTION,

  CONSTRAINT tblproduct_size_fkey FOREIGN KEY (size)

      REFERENCES tblsize (sizecode) MATCH SIMPLE

      ON UPDATE NO ACTION ON DELETE NO ACTION

)


CREATE TABLE tblcolor

(

  colorname text NOT NULL,

  colorcode serial NOT NULL,

  CONSTRAINT tblcolor_pkey PRIMARY KEY (colorcode)

)


CREATE TABLE tblsize

(

  sizename text NOT NULL,

  sizecode integer NOT NULL DEFAULT nextval('tblsize_colorcode_seq'::regclass),

  CONSTRAINT tblsize_pkey PRIMARY KEY (sizecode)

)


view는 다음과 같습니다.


CREATE OR REPLACE VIEW qryproduct AS

 SELECT tblproduct.productname, tblcolor.colorname, tblsize.sizename

   FROM tblproduct

   JOIN tblcolor ON tblproduct.color = tblcolor.colorcode

   JOIN tblsize ON tblproduct.size = tblsize.sizecode;


view를 통해서 update, insert, delete를 구현해야 하는데, 워낙 DB상식이 없어서인지

매뉴얼 보고 rule을 만들어보는데 계속 에러만 나옵니다.


postgresql 매뉴얼 chapter 35장 오늘 10번 넘게 읽었네요....에효....

도움 주시면 넘 감사히 받겠습니다.


(--)(__)(--)


이 글에 대한 댓글이 총 8건 있습니다.

만들어보신 rule도 올려보시면 좋을텐데요...

어떤 경우인지 파악이 잘안되지만 

view를 통해서 update, insert, delete를 구현하는건 rule로 해결할게 아닌듯함니다.

view와는 무관하게 내부에서 update, insert, delete가 조건에 따라 자동으로 이루어질 수 있는 경우라면 그건 rule이 적당하겟지만요





가우님이 2008-01-11 16:45에 작성한 댓글입니다. Edit

insert into qryproduct values (..);


이런 형식을 말씀하시는거 같은데...


create rule rulename as on insert to qryproduct do INSTEAD (

 ..... bla bla query;

...... baz baz query;

...

);


이런식이면 될거 같습니다만..

tyro님이 2008-01-11 22:59에 작성한 댓글입니다. Edit

tblcolor

colorname

colorcode

White

1

Black

2

Navy

3


tblsize

sizename

sizecode

Small

1

Medium

2

Large

3


tblproduct

productname

color

size

yourclothing

1

2

hisclothing

2

1

herclothing

2

2

girlclothing

3

1

myclothing

1

2


qryproduct (view)

productname

colorname

sizename

yourclothing

White

Medium

hisclothing

Black

Small

herclothing

Black

Medium

girlclothing

Navy

Small

myclothing

White

Medium


먼저 테이블과 view 는 위와 같습니다.

SQL을 통해서 구현하고자 하는 바는 다음과 같습니다.

UPDATE qryproduct
SET colorname='Black', sizename='Small'
WHERE productname='myclothing';

보시다시피 실제로 바뀌어야하는 부분은 tblproduct의  color, size가 FK로연결된 
tblcolor 와 tblsize의 colorcode, sizecode 의 참조 부분이여야하죠.



rule은 다음과 같이 만들었습니다.


CREATE OR REPLACE RULE qryproduct_update AS

    ON UPDATE TO qryproduct DO INSTEAD  

UPDATE tblproduct SET color = ( SELECT tblcolor.colorcode FROM tblcolor WHERE 

                                                tblcolor.colorname = new.colorname), 

                                    size = ( SELECT tblsize.sizecode FROM tblsize WHERE 

                                                  tblsize.sizename = new.sizename), 

                                   productname = new.productname;


위와 같은 상황에서 SQL 결과는...

productname

colorname

sizename

myclothing

Black

Small

myclothing

Black

Small

myclothing

Black

Small

myclothing

Black

Small

myclothing

Black

Small



row 5 개가 일괄적으로 다 바뀌어 버립니다.

보다시피 제가 적은 rule 이 논리적으로 맞지않습니다.

Update 부분에서 color, size, productname 은 "new"라는 table alias를 통해 얻을 수있지만 WHERE 이하 부분을 얻어낼 수가 없군요.
더우기 WHERE 가 color가 될지 size가 될지 모릅니다. 

위의 가우님 설명처럼 rule은 update, insert, delete등의 이벤트가 생길때 어떤 SQL 이 씌여지던 상관없이 (DO INSTEAD 경우) 실행되는건지요?

Rule 이 아니라면 다른 부분(function ?, trigger ?)을 통해서 여러 테이블이 연결되어있는 view를 테이블 처럼 update, insert, delete 할수 있는 방법이 있나요?

읽어주셔서 감사합니다.



님이 2008-01-12 04:08에 작성한 댓글입니다. Edit

rule 에서 where 절이 빠졌는데요?



create rule .................... do instead

update tblproduct set color = (select .....),

                               size = (select ....)

where productname = new.productname;


제일 마지막 부분의 where 가 빠졌습니다.


try님이 2008-01-12 11:40에 작성한 댓글입니다. Edit

네 try님 알고있습니다. 

문제는 qryproduct를 update시 WHERE 다음시 어떤 구절이 올지 모르기때문이죠...
예제는 위 UPDATE SQL 이지만,

UPDATE qryproduct
SET colorname='Black',  productname='prettyclothing'
WHERE sizename='Small';


로 바뀌어 쓰일 수도 있습니다.

상황이, DB가 MSACCESS + VB로 만들어진 클라이언트 프로그램인데 데이타가 많아지면서 DB를 postgresql로 바꾸려고합니다. ACCESS 에 테이블이 여럿있고 view(ACCESS 표현으론 쿼리구문 저장된것)를 통해서 업데이트가 되도록 이미 코딩이 되어있어서, postgresql에서view를 통한 업데이트가 안되면 코딩을 바꿔야하는양이 많아지고 프로그램 flow자체도 바뀌는게 많아서 그럽니다...

전홍준(noidda)님이 2008-01-12 13:39에 작성한 댓글입니다.

그럼 이런식으로 하면 되겠군요...



create rule myrule as on update to qryproduct do instead (                   

  update tblproduct set color = (case when new.colorname is not null then

                               (select colorcode from tblcolor

                                where colorname = new.colorname)

                              else color end),

                     size = (case when new.sizename is not null then

                               (select sizecode from tblsize

                                where sizename = new.sizename)

                             else size end),

                     productname = (case when new.productname is not null

                                         then new.productname

                                         else productname end)

  where product_unique_col = new.product_unique_col

);


물론 여기서는 update 할 col 의 값에 null 이 들어가면 안 된다는 조건이 있어야 하죠..

만일 null 을 입력할 일이 생긴다면 특별히 쓰지 않는 문자를 nulll 대신 정하고  is not null 대신 <> '문자' 형태로 해도 되겠죠..

숫자엔 숫자겠고요...


그리고 view 에서 tblproduct 에서 유니크 키값을 select 해주고

rule 의 where 절에 그 키값을 비교하면 되겠죠

tryo님이 2008-01-12 17:00에 작성한 댓글입니다. Edit

아 이거 자꾸 닉네임에 오타를 치네요 ^^;


tyro 였습니다.


tyro님이 2008-01-12 17:04에 작성한 댓글입니다. Edit

성능같은건 놔두고 알아보기 쉽게하면 
아래처럼해도 되겟네요

create or replace rule r_qryproduct as on update to qryproduct
do instead
(
  update  tblproduct
   set color = tblcolor.colorcode ,size = tblsize.sizecode
  from tblcolor,tblsize
  where tblcolor.colorname = coalesce(new.colorname,old.colorname)
    and tblsize.sizename = coalesce(new.sizename,old.sizename)
    and productname = new.productname
);

가우님이 2008-01-14 19:12에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
7306./configure 시 문제가 생깁니다.(다시) [2]
도움좀
2008-01-15
6262
7305클라이언트가 접속이 끊어졌는지 실시간으로 감시는 어떻게? [1]
심상호
2008-01-14
5810
7304RANK 쿼리문을 만들어 봤습니다. [1]
tyro
2008-01-11
6314
7303view 에서 rule적용 질문 (update, insert, delete) [8]
전홍준
2008-01-11
6625
7302postgresql 초기 설치 방법 [1]
권태영
2008-01-09
10520
7301postGIS 관련 질문요~ㅜ.ㅜ [1]
기초인
2008-01-09
6692
7297md5설정에 관해서 [2]
영광
2008-01-04
6181
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.017초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다