배열 (Array) 필드를 취급하는 방법은 약간 까다로운 면이 있습니다. 하지만 특성을 어느 정도 이해하고 나면 비교적 손쉽게 다룰수 있고, 굉장히 편리하게 사용할 수 있습니다.
다음은 배열컬럼에 입출력하는 방법을 간단한 예로서 표현한 것입니다. 참고 바랍니다. 아래에 간단한 주석을 달도록 하겠습니다.
pgbash> create table t (id int, opt text[]);
CREATE
pgbash> insert into t values (1,'\');
INSERT 2434120 1
배열값의 첫요소를 배열 첨자를 명시하지 않고 입력시에는 '' 이런식으로 명시해 주어야 합니다.
pgbash> select * from t;
id|opt
--+-----------
1|
(1 row)
pgbash> update t set opt[1]='advances';
UPDATE 1
pgbash> select * from t;
id|opt
--+--------------
1|
(1 row)
만약 "advances" 라는 단어를 opt[1] 에 넣기를 원했다면 이것은 틀린 문장입니다. 대신 opt[1]='advances' 라고 적어 줘야 제대로 원하는 값이 입력됩니다. 현재는 '' 라는 '{}' 이 포함된 문자열이 입력되어 있습니다.
pgbash> update t set opt[1]=;
Error SQL : update t set opt[1]=
(-403)ERROR: parser: parse error at or near "{"
이것역시 틀린 것입니다. 왜 틀렸는지는 알겠지요. 그냥 바로 이런식의 명시는 불가합니다. 물론 opt[1] 에 '{}' 로서 문자열을 감싸주는 것도 원치 않는 효과를 나타낸다는 것 알겠지요.
pgbash> update t set opt[2]='advance';
UPDATE 1
pgbash> update t set opt[1]='advance';
UPDATE 1
pgbash> select * from t;
id|opt
--+---------------------
1|
(1 row)
이제야 올바르게 우리가 원하는 바를 입력했습니다. 참 어렵지요. 하지만 이것만 이해하면 배열 입력의 첫걸음을 땐 것입니다.
pgbash> insert into t values (2,'');
(-403)ERROR: array_in: Need to specify dimension
왜 틀렸을까요. 어느 배열 요소에 '' 문자열을 입력할지 제대로 명시하지 않은 것입니다. 만약 배열요소를 명시하지 않고 배열 컬럼에 입력하길 원한다면 '' 또는 '{}' 이런식으로 입력해 줘야만이 배열컬럼에 NULL array '{}' 이 들어간다는 것까지는 이해하시겠죠.
pgbash> insert into t values (2,'');
INSERT 2434162 1
pgbash> select * from t;
id|opt
--+---------------------
1|
2|
(2 rows)
pgbash> select opt[1] from t;
opt
-------
advance
aaa
(2 rows)
pgbash> select opt[2] from t;
opt
-------
advance
(2 rows)
여기까지는 무난하게 이해가 가실 것으로 믿습니다. 참고로 두번째 열의 opt[2] 는 값자체가 NULL 입니다.
pgbash> insert into t values (3,'{}');
INSERT 2434163 1
pgbash> select * from t;
id|opt
--+---------------------
1|
2|
3|{}
(3 rows)
여기서 id=3 인 row 의 opt 배열컬럼의 값은 NULL array 입니다. 이것은 '{}' 을 뜻하며 자체의 값이 'NULL' 은 아닙니다. 이 둘은 중요한 차이가 있습니다.
만약 select * from t where opt is null; 라는 query 를 주었을 경우 opt='{}' 인 row 는 SELECT 되지 않습니다. 비록 NULL array 이지만 값 자체가 NULL 은 아니기 때문입니다. 하지만 select * from t where opt[1] is NULL; 이라는 query 를 주었을때에는 opt='{}' 인 row 가 포함되어 SELECT 됩니다. array 내의 배열요소의 값들이 NULL 이기 때문이지요.
pgbash> update t set opt[1]='ttt' where id=3;
(-403)ERROR: Invalid array subscripts
이것은 당연한 결과입니다. opt 컬럼 자체의 값이 NULL array 이기 때문에 그 요소가 없습니다. 그러니 opt[1] 이라는 배열요소가 없기 때문에 opt[1]='ttt' 라고 명시해 준 것 자체가 잘못이기 때문입니다. 이 부분에 많은 오류를 일으키는 경우가 많습니다. 명심해 주시기 바랍니다.
pgbash> update t set opt[]='ttt' where id=3;
Error SQL : update t set opt[]='ttt' where id=3
(-403)ERROR: parser: parse error at or near "]"
이것 역시 틀린 명시법입니다. 이유는 앞의 것과 비슷합니다. SET 절에서는 이미 존재하는 배열요소를 적어줘야 하는데 opt[] 라고 명시해 주면 어쩌면 기존의 배열요소 다음에 추가적으로 하나더 배열 요소를 첨가해 줄지도 모른다는 착각을 일으킬수도 있는데 그렇지 않습니다. SET 절에서는 반드시 기존에 정의된 배열요소에 대해서만 변경 가능하다는 것을 명심하시면 될 것 같습니다.
pgbash> update t set opt='' where id=3;
UPDATE 1
pgbash> select * from t;
id|opt
--+---------------------
1|
2|
3|
(3 rows)
pgbash>
이제야 제대로 update 를 한것 같군요. 이미 기존의 배열 요소가 없었기 때문에 첫배열을 변경시켜 주기 위해서 이런 방식을 사용한 것입니다. 이제는 배열요소를 직접 명시하여 변경이 가능합니다.
pgbash> update t set opt[1]='aaa' where id=3;
UPDATE 1
pgbash> select * from t;
id|opt
--+---------------------
1|
2|
3|
(3 rows)
이제는 이런 결과를 이해할 수 있을 것으로 생각됩니다. opt[1] 배열요소가 존재하기 때문에 바로 opt[1] 이라는 배열 요소를 SET 절에 직접 언급이 가능한 것입니다.
여기 정도까지 설명하겠습니다. 간단한 문제이고, 테스트해 보면 알수 있는 내용이지만 메뉴얼에 적혀 있지 않는 내용이라서 장황하게 적어 보았습니다. 참조하시기 바랍니다.
혹시 틀린 부분이 있다면 reply 를 달아 주시기 바랍니다.
-- 소타 님이 쓰신 글:
|