# SQL 조건문
이 페이지의 내용은 MySQL 기준으로 작성했습니다.
PostgreSQL와 다른 데이터베이스 쿼리의 경우 별도 표시를 해두었습니다.
# 셀렉트는 Bind Parameter / Prepared Statements를 기본으로 합니다.
SQL 보안을 위해 번거롭더라도 원본 raw query 입력을 원칙적으로 막고 있습니다.
인가된 사용자만 어드민 시스템을 이용한다고 하더라도 동일 네트워크상 세션탈취나 기타 물리적인 침입/침해를 막기 위해 보안 가이드라인을 제공하고 있습니다.
더 향상된 보안을 위해 Enterprise 플랜에서는 general query log의 anomaly scoring을 제공합니다.
# 검색조건 필수
빈칸이면 결과물 없음
SELECT *
FROM users
WHERE name = :name
1
2
3
2
3
# 검색조건 옵션
CASE-WHEN 활용
SELECT *
FROM users
WHERE status = 'active'
AND CASE
WHEN LENGTH(:name) THEN name = :name
ELSE 1=1
END
1
2
3
4
5
6
7
2
3
4
5
6
7
빈칸이면 해당 조건 없이 결과물 표시
SELECT *
FROM users
WHERE status = 'active'
AND (!LENGTH(:name) OR name = :name)
1
2
3
4
2
3
4
PostgreSQL: 빈칸이면 해당 조건 없이 결과물 표시
SELECT *
FROM users
WHERE status = 'active'
AND (LENGTH(:name) = 0 OR name = :name)
1
2
3
4
2
3
4
# 검색조건 LIKE
MySQL
SELECT *
FROM users
WHERE name LIKE CONCAT('%', :name, '%')
1
2
3
2
3
PostgreSQL: 타입 지정 필요
SELECT *
FROM users
WHERE name LIKE CONCAT('%', :name::text, '%')
1
2
3
2
3
# 검색조건에 따른 쿼리입력
types
값에 해당하는 쿼리가 안전하게 bind 됩니다.
sql: >
SELECT *
FROM properties
WHERE name LIKE CONCAT('%', :name, '%')
AND {{query}}
LIMIT 1000
params:
- key: name
label: 숙소명
- key: types
label: 숙소타입
query:
'': >
`type` = :types
'HOTEL': >
`type` = 'HOTEL'
'NON HOTEL': >
`type` IN ('GUESTHOUSE', 'BNB')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
types
에 NON HOTEL
값이 들어가는 경우 실제 실행 쿼리는 다음과 같습니다.
SELECT *
FROM properties
WHERE name LIKE CONCAT('%', :name, '%')
AND `type` IN ('GUESTHOUSE', 'BNB') AND 1=1
LIMIT 1000
1
2
3
4
5
2
3
4
5
# 검색조건에 따른 쿼리 정렬
pages:
- path: property/list
blocks:
- type: query
resource: mysql
name: 업체목록
sqlType: select
sql: >
SELECT *
FROM property
{{ orderBy }}
LIMIT 100
params:
- key: orderby
label: 정렬
defaultValue: 최근가입순
dropdownSize: 2
dropdown:
- 최근가입순
- 오래된가입순
orderBy:
'최근가입순': ORDER BY id DESC
'오래된가입순': ORDER BY id ASC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 날짜 검색조건 기본값
CASE-WHEN 활용
SELECT
id, active, name, email, created_at, last_updated, trial_expiry_date
FROM s_users
WHERE CASE WHEN LENGTH(:user_id) THEN id = :user_id ELSE 1=1 END
AND CASE WHEN LENGTH(:user_name) THEN name LIKE CONCAT('%', :user_name, '%') ELSE 1=1 END
AND CASE WHEN LENGTH(:signed_up) THEN created_at >= GREATEST('2000-01-01', :signed_up) ELSE 1=1 END
1
2
3
4
5
6
2
3
4
5
6
위와 동일 합니다.
SELECT
id, active, name, email, created_at, last_updated, trial_expiry_date
FROM s_users
WHERE (!LENGTH(:user_id) OR id = :user_id)
AND (!LENGTH(:user_name) OR name LIKE CONCAT('%', :user_name, '%'))
AND (!LENGTH(:signed_up) OR created_at >= GREATEST('2000-01-01', :signed_up))
1
2
3
4
5
6
2
3
4
5
6
# 여러 항목 UPDATE
number
는 Number 숫자로 escape하여 들어갑니다.
user_ids
는 Array/List로 각 항목을 알맞게 escape하여 들어갑니다.
pages:
- path: customer/support
blocks:
- type: query
resource: mysql
sqlType: select
sql: >
SELECT
id AS '고객ID',
active AS '활성', name AS '이름', email AS '이메일',
created_at AS '생성일', last_updated AS '최근수정일',
trial_expiry_date AS '만료일'
FROM s_users
selectOptions:
enabled: true
selectionText: 건 선택됨
clearSelectionText: 취소
selectOnCheckboxOnly: true
disableSelectInfo: true
actions:
- label: 만료일 연장
type: query
resource: mysql
sql: >
UPDATE s_users
SET trial_expiry_date = NOW() + INTERVAL :number DAY
WHERE id IN (:user_ids)
valueFromSelectedRowsAs: 고객ID
params:
- key: number
label: 만료일 연장 (D+1)
dropdown:
- 1
- 4
- 7
- 14
required: true
- key: user_ids
valueFromSelectedRows: true
valueFromSelectedRowsAs: 고객ID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 검색조건 IN
비어있는 IN ()
으로 에러가 나는 경우 빈값 IN ('', :tags)
또는 IN (0, :ids)
을 넣습니다.
- path: stock-a/return
blocks:
- type: query
resource: mysql.qa
sqlType: select
sql: >
SELECT name FROM test_10k
WHERE name IN ('', :tag)
LIMIT 100
params:
- key: tag
label: Tag
datalist: true
datalistLength: 5
datalistFromQuery:
type: query
resource: mysql.qa
sqlType: select
sql: SELECT DISTINCT name FROM test_10k LIMIT 10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 계속 업데이트 예정입니다.
궁금하신 점은 문의바랍니다.
← 추가 문의