> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> Template 형식 문서

# Template

| 입력 | 출력 | 별칭 |
| -- | -- | -- |
| ✔  | ✔  |    |

<div id="description">
  ## 설명
</div>

다른 표준 포맷으로는 부족할 정도로 더 세밀한 사용자 지정이 필요한 경우,
`Template` 형식을 사용하면 값용 placeholder가 포함된 사용자 정의 포맷 문자열을 직접 지정하고,
데이터의 이스케이프 규칙도 지정할 수 있습니다.

다음 설정을 사용합니다:

| Setting                                                                                                  | Description                                                                |
| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| [`format_template_row`](#format_template_row)                                                            | 행의 포맷 문자열이 들어 있는 파일의 경로를 지정합니다.                                            |
| [`format_template_resultset`](#format_template_resultset)                                                | 행의 포맷 문자열이 들어 있는 파일의 경로를 지정합니다.                                            |
| [`format_template_rows_between_delimiter`](#format_template_rows_between_delimiter)                      | 행 사이의 구분자를 지정합니다. 마지막 행을 제외한 각 행 뒤에 출력되거나(또는 입력 시 기대되는 값이며), 기본값은 `\n`입니다. |
| `format_template_row_format`                                                                             | 행의 포맷 문자열을 [인라인](#inline_specification)으로 지정합니다.                           |
| `format_template_resultset_format`                                                                       | 결과 집합 포맷 문자열을 [인라인](#inline_specification)으로 지정합니다.                        |
| Some settings of other formats (e.g.`output_format_json_quote_64bit_integers` when using `JSON` escaping |                                                                            |

<div id="settings-and-escaping-rules">
  ## 설정 및 이스케이프 규칙
</div>

<div id="format_template_row">
  ### format\_template\_row
</div>

설정 `format_template_row`는 다음 구문에 사용되는 행의 포맷 문자열이 들어 있는 파일의 경로를 지정합니다:

```text theme={null}
delimiter_1${column_1:serializeAs_1}delimiter_2${column_2:serializeAs_2} ... delimiter_N
```

다음과 같습니다.

| 구문의 부분          | 설명                                                  |
| --------------- | --------------------------------------------------- |
| `delimiter_i`   | 값 사이의 구분자(`$` 기호는 `$$`로 이스케이프할 수 있음)                |
| `column_i`      | 선택하거나 삽입할 값이 들어 있는 컬럼의 이름 또는 인덱스(비어 있으면 해당 컬럼은 건너뜀) |
| `serializeAs_i` | 컬럼 값에 적용할 이스케이프 규칙입니다.                              |

다음 이스케이프 규칙을 지원합니다.

| 이스케이프 규칙             | 설명                       |
| -------------------- | ------------------------ |
| `CSV`, `JSON`, `XML` | 같은 이름의 포맷과 유사합니다         |
| `Escaped`            | `TSV`와 유사합니다             |
| `Quoted`             | `Values`와 유사합니다          |
| `Raw`                | 이스케이프 없이 `TSVRaw`와 유사합니다 |
| `None`               | 이스케이프 규칙이 없음 - 아래 참고     |

<Note>
  이스케이프 규칙을 생략하면 `None`이 사용됩니다. `XML`은 출력에만 적합합니다.
</Note>

예시를 살펴보겠습니다. 다음 포맷 문자열이 있다고 가정합니다.

```text theme={null}
Search phrase: ${s:Quoted}, count: ${c:Escaped}, ad price: $$${p:JSON};
```

다음 값은 `SELECT`를 사용하는 경우 출력되고 `INPUT`을 사용하는 경우 기대되며,
각각 컬럼 구분 기호 `Search phrase:`, `, count:`, `, ad price: $`, `;` 사이에 위치합니다:

* `s` (이스케이프 규칙 `Quoted` 적용)
* `c` (이스케이프 규칙 `Escaped` 적용)
* `p` (이스케이프 규칙 `JSON` 적용)

예시:

* `INSERT`하는 경우, 아래 줄은 기대되는 Template과 일치하며 값 `bathroom interior design`, `2166`, `$3`를 컬럼 `Search phrase`, `count`, `ad price`에 읽어옵니다.
* `SELECT`하는 경우, 아래 줄은 출력 결과이며 값 `bathroom interior design`, `2166`, `$3`가 이미 테이블의 컬럼 `Search phrase`, `count`, `ad price`에 저장되어 있다고 가정합니다.

```yaml theme={null}
Search phrase: 'bathroom interior design', count: 2166, ad price: $3;
```

<div id="format_template_rows_between_delimiter">
  ### format\_template\_rows\_between\_delimiter
</div>

`format_template_rows_between_delimiter` 설정은 행 사이의 구분자를 지정합니다. 이 구분자는 마지막 행을 제외한 각 행 뒤에 출력되거나(또는 입력에서 필요로 하는 값으로) 사용됩니다(기본값은 `\n`).

<div id="format_template_resultset">
  ### format\_template\_resultset
</div>

`format_template_resultset` 설정은 결과 집합(result set)의 포맷 문자열이 들어 있는 파일 경로를 지정합니다.

결과 집합의 포맷 문자열은 행에 대한 포맷 문자열과 동일한 구문을 사용합니다.
접두사, 접미사, 일부 추가 정보를 출력하는 방법을 지정할 수 있으며, 컬럼 이름 대신 다음 placeholder를 포함합니다:

* `data`는 `format_template_row` 포맷의 데이터 행들이며, `format_template_rows_between_delimiter`로 구분됩니다. 이 placeholder는 포맷 문자열의 첫 번째 placeholder여야 합니다.
* `totals`는 `format_template_row` 포맷의 합계 값 행입니다(WITH TOTALS 사용 시).
* `min`은 `format_template_row` 포맷의 최솟값 행입니다(extremes가 1로 설정된 경우).
* `max`는 `format_template_row` 포맷의 최댓값 행입니다(extremes가 1로 설정된 경우).
* `rows`는 출력 행의 총개수입니다.
* `rows_before_limit`는 LIMIT가 없었을 경우의 최소 행 수입니다. 쿼리에 LIMIT가 포함된 경우에만 출력됩니다. 쿼리에 GROUP BY가 포함된 경우, rows\_before\_limit\_at\_least는 LIMIT가 없었을 경우의 정확한 행 수입니다.
* `time`은 요청 실행 시간(초)입니다.
* `rows_read`는 읽은 행 수입니다.
* `bytes_read`는 읽은 바이트 수(비압축 기준)입니다.

`data`, `totals`, `min`, `max` placeholder에는 이스케이프 규칙을 지정하면 안 됩니다(또는 `None`을 명시적으로 지정해야 합니다). 나머지 placeholder에는 어떤 이스케이프 규칙이든 지정할 수 있습니다.

<Note>
  `format_template_resultset` 설정이 빈 문자열이면 기본값으로 `${data}`가 사용됩니다.
</Note>

삽입 쿼리 포맷에서는 접두사나 접미사가 있는 경우 일부 컬럼 또는 필드를 스키핑할 수 있습니다(예시 참조).

<div id="inline_specification">
  ### 인라인 지정
</div>

클러스터의 모든 노드에서 디렉터리에 Template 형식의 포맷 구성
(`format_template_row`, `format_template_resultset`로 설정)을 배포하는 것은 종종 어렵거나 불가능할 수 있습니다.
또한 포맷이 매우 단순해서 파일에 둘 필요가 없을 수도 있습니다.

이런 경우 `format_template_row_format`(`format_template_row`용)과 `format_template_resultset_format`(`format_template_resultset`용)을 사용하면, 이를 포함하는 파일의 경로를 지정하는 대신 템플릿 문자열을 쿼리에서 직접 설정할 수 있습니다.

<Note>
  포맷 문자열과 이스케이프 시퀀스에 대한 규칙은 다음과 같습니다:

  * `format_template_row_format`를 사용할 때는 [`format_template_row`](#format_template_row)의 규칙과 동일합니다.
  * `format_template_resultset_format`를 사용할 때는 [`format_template_resultset`](#format_template_resultset)의 규칙과 동일합니다.
</Note>

<div id="example-usage">
  ## 사용 예시
</div>

`Template` 형식을 사용하는 두 가지 예시를 살펴보겠습니다. 먼저 데이터를 선택하는 경우를 보고, 그다음 데이터를 삽입하는 경우를 살펴보겠습니다.

<div id="selecting-data">
  ### 데이터 조회
</div>

```sql title="Query" theme={null}
SELECT SearchPhrase, count() AS c FROM test.hits GROUP BY SearchPhrase ORDER BY c DESC LIMIT 5 FORMAT Template SETTINGS
format_template_resultset = '/some/path/resultset.format', format_template_row = '/some/path/row.format', format_template_rows_between_delimiter = '\n    '
```

```text title="/some/path/resultset.format" theme={null}
<!DOCTYPE HTML>
<html> <head> <title>Search phrases</title> </head>
 <body>
  <table border="1"> <caption>Search phrases</caption>
    <tr> <th>Search phrase</th> <th>Count</th> </tr>
    ${data}
  </table>
  <table border="1"> <caption>Max</caption>
    ${max}
  </table>
  <b>Processed ${rows_read:XML} rows in ${time:XML} sec</b>
 </body>
</html>
```

```text title="/some/path/row.format" theme={null}
<tr> <td>${0:XML}</td> <td>${1:XML}</td> </tr>
```

```html title="Response" theme={null}
<!DOCTYPE HTML>
<html> <head> <title>Search phrases</title> </head>
 <body>
  <table border="1"> <caption>Search phrases</caption>
    <tr> <th>Search phrase</th> <th>Count</th> </tr>
    <tr> <td></td> <td>8267016</td> </tr>
    <tr> <td>bathroom interior design</td> <td>2166</td> </tr>
    <tr> <td>clickhouse</td> <td>1655</td> </tr>
    <tr> <td>spring 2014 fashion</td> <td>1549</td> </tr>
    <tr> <td>freeform photos</td> <td>1480</td> </tr>
  </table>
  <table border="1"> <caption>Max</caption>
    <tr> <td></td> <td>8873898</td> </tr>
  </table>
  <b>Processed 3095973 rows in 0.1569913 sec</b>
 </body>
</html>
```

<div id="inserting-data">
  ### 데이터 삽입
</div>

```text theme={null}
Some header
Page views: 5, User id: 4324182021466249494, Useless field: hello, Duration: 146, Sign: -1
Page views: 6, User id: 4324182021466249494, Useless field: world, Duration: 185, Sign: 1
Total rows: 2
```

```sql theme={null}
INSERT INTO UserActivity SETTINGS
format_template_resultset = '/some/path/resultset.format', format_template_row = '/some/path/row.format'
FORMAT Template
```

```text title="/some/path/resultset.format" theme={null}
Some header\n${data}\nTotal rows: ${:CSV}\n
```

```text title="/some/path/row.format" theme={null}
Page views: ${PageViews:CSV}, User id: ${UserID:CSV}, Useless field: ${:CSV}, Duration: ${Duration:CSV}, Sign: ${Sign:CSV}
```

플레이스홀더 안의 `PageViews`, `UserID`, `Duration`, `Sign`은 테이블의 컬럼 이름입니다. 행에서 `Useless field` 뒤에 오는 값과 접미사에서 `\nTotal rows:` 뒤에 오는 값은 무시됩니다.
입력 데이터의 모든 구분 기호는 지정된 포맷 문자열의 구분 기호와 정확히 일치해야 합니다.

<div id="inline_specification">
  ### 인라인 지정
</div>

Markdown 표를 수동으로 포맷하느라 번거로우셨나요? 이 예시에서는 `Template` 형식과 인라인 지정 설정을 사용해 간단한 작업을 수행하는 방법을 살펴보겠습니다. 즉, `system.formats` 테이블에서 몇 가지 ClickHouse 포맷의 이름을 `SELECT`한 뒤 이를 Markdown 표로 포맷하는 방법입니다. 이는 `Template` 형식과 `format_template_row_format`, `format_template_resultset_format` 설정을 사용하면 쉽게 구현할 수 있습니다.

이전 예시에서는 결과 집합과 행 포맷 문자열을 각각 별도의 파일에 지정하고, 해당 파일의 경로를 각각 `format_template_resultset` 및 `format_template_row` 설정으로 지정했습니다. 여기서는 템플릿이 Markdown 표를 만드는 데 필요한 몇 개의 `|`와 `-`만으로 이루어질 정도로 단순하므로 인라인으로 지정하겠습니다. 결과 집합 템플릿 문자열은 `format_template_resultset_format` 설정을 사용해 지정합니다. 표 헤더를 만들기 위해 `${data}` 앞에 `|ClickHouse Formats|\n|---|\n`를 추가했습니다. 행 템플릿 문자열 ``|`{0:XML}`|``은 `format_template_row_format` 설정을 사용해 지정합니다. `Template` 형식은 지정된 포맷의 행을 `${data}` 플레이스홀더에 삽입합니다. 이 예시에서는 컬럼이 하나뿐이지만, 더 추가하려면 행 템플릿 문자열에 `{1:XML}`, `{2:XML}` 등을 추가하면 됩니다. 이때 적절한 이스케이프 규칙을 선택하십시오. 이 예시에서는 `XML` 이스케이프 규칙을 사용했습니다.

```sql title="Query" theme={null}
WITH formats AS
(
 SELECT * FROM system.formats
 ORDER BY rand()
 LIMIT 5
)
SELECT * FROM formats
FORMAT Template
SETTINGS
 format_template_row_format='|`${0:XML}`|',
 format_template_resultset_format='|ClickHouse Formats|\n|---|\n${data}\n'
```

보세요! 이제 마크다운 표를 만들 때 그 많은 `|`와 `-`를 일일이 직접 추가하는 수고를 덜었습니다:

```response title="Response" theme={null}
|ClickHouse Formats|
|---|
|`BSONEachRow`|
|`CustomSeparatedWithNames`|
|`Prometheus`|
|`DWARF`|
|`Avro`|
```
