본문 바로가기

DataBase

[PostgreSQL] 파일 이름이 콤마(,)를 기준으로 두 개로 나뉘는 문제

SELECT
    ARRAY_TO_STRING(ARRAY_AGG(attachfile.file_name), ',')
FROM
    attachfile
WHERE
    attachfile.seq_num = 163
<c:set var="fileNameList" value="${fn:split(notice.attachFileNames, ',')}"/>
<c:forEach var="fileName" items="${fileNameList}" varStatus="g">
     <button<c:out value="${fileName}/> </button>
<c:forEach>



게시물이 하나 있다
게시물 하나에 첨부 파일은 여러 개 등록할 수 있다.
디비에서 받아올 때는 게시물 하나당 첨부파일들을 여러 개 가져와야 한다.
이때 첨부 파일 이름들을 콤마 ( , )로 붙여서 가져온다.
화면에서는 그 이름들을 다시 ( , )를 구분자로 써서 자른다.
자른 이름들이 하나씩 들어 있는 list가 만들어진다.
이 list를 가지고 forEach를 돌린다.
그러면 첨부파일 하나당 다운로드 버튼 하나씩을 만들 수 있다.
전체적으로 이런 로직이다.

 


문제는 첨부파일 이름에 콤마가 쓰일 수 있다는 점이다
[~~~], [~~~~~~], [~~~]
이렇게 세 개응 가져오면 콤마를 구분자로 해서 세 개로 나누어져야 한다.
근데 파일 이름 안에 콤마가 들어가 버리면 제대로 나누지를 못한다.
[~~~], [~~,~~~~], [~,~~]
이럴 때는 콤마를 기준으로 나누면 다섯 개가 나온다.
예를 들어 [test,img-2.jpg] 라는 이름으로 파일이 있으면 
콤마를 기준으로 나누었을 때 [test]로 하나 나누고 [img-2.jpg]로 하나 나누어서 
버튼이 총 두 개가 만들어진다.

 


이 문재를 어떻게 해결해야 할까?
DB쿼리를 살펴봤다.
구분자로 콤마(,)를 넣어주는 부분을 찾았다

ARRAY_TO_STRING(ARRAY_AGG(attachfile.file_name), ',')


하나씩 뜯어 보면 이렇다.

 


ARRAY_AGG()

=> row들을 array로 만드는 함수다
=> 예를 들어 아래처럼 나온다
    fruit   |   color
    --------|--------
    apple   |   red
    apple   |   green
    banana  |   yellow
=>
    fruit   |   color
    --------|--------
    apple   |   red, green
    banana  |   yellow
=> 이렇게 해서 가져온 결과는 배열이 된다.
    {red, blue, green, yellow}
이대로 사용해도 상관은 없지만, 프론트에서 사용할 때는 배열로 가지고 와서 쓰는 것보다는 문자열로 바꿔서 사용하는 쪽이 더 편하다.
이때 이용하는 함수가 아래 함수가 필요하다.

 


ARRAY_TO_STRING(arr, separator)

=> array를 string으로 출력하는 함수다.
=> 전달인자는 총 두 개를 받으며, 첫 번째는 이어붙일 배열을 받고, 두 번째는 이어붙여주는 구분자를 넣어준다.


SELECT
    ARRAY_TO_STRING(ARRAY_AGG(attachfile.file_name), ',')
FROM
    attachfile
WHERE
    attachfile.seq_num = 163


알아본 바를 토대로 위 쿼리를 해석해 보자.



attachfile 이라는 테이블에서 seq_num가 163인 로우들을 찾고,
그 로우들이 갖는 file_name라는 칼럼의 값들 사이에
콤마(,)를 넣어서 배열로 만든 뒤 받아오고,
그것을 배열로 두지 말고 문자열로 바꿔서 가져오겠다.

이 부분에서 우리는 콤마( , )를 파이프( | )로 바꿔 주자.
( | )는 평소에 거의 사용할 일이 없는 문자이기도 하고,
파일 이름으로는 사용할 수 없는 문자이므로
파일 하나가 두 개로 나누어지는 일은 없을 것이다.

따라서 아래와 같이 수정했다.

SELECT
    ARRAY_TO_STRING(ARRAY_AGG(attachfile.file_name), '|')
FROM
    attachfile
WHERE
    attachfile.seq_num = 163
<c:set var="fileNameList" value="${fn:split(notice.attachFileNames, '|')}"/>
<c:forEach var="fileName" items="${fileNameList}" varStatus="g">
     <button<c:out value="${fileName}/> </button>
<c:forEach>




- 220621

반응형