정형 데이터 타입

정형 데이터 타입 (Structured data types)

Snowflake의 정형 타입(structured types)인 ARRAY, OBJECT, MAP을 다루는 문서예요. 정형 타입은 특정 Snowflake 데이터 타입의 요소나 키-값 쌍을 담아요. 타입 지정 방법, 테이블 생성, 캐스팅·강제 변환, 값 구성, 키·값·요소 다루기, 비교, 변환, FLATTEN·UDF 적용, 드라이버 접근을 확인할 수 있어요.

출처: Snowflake SQL Reference

본문

Snowflake 정형 타입은 ARRAY, OBJECT, MAP이에요. 정형 타입은 특정 Snowflake 데이터 타입의 요소 또는 키-값 쌍을 포함해요. 정형 타입의 예는 다음과 같아요.

  • INTEGER 요소의 ARRAY.
  • VARCHAR와 NUMBER 키-값 쌍이 있는 OBJECT.
  • VARCHAR 키를 DOUBLE 값과 연결하는 MAP.

정형 타입은 다음 방법으로 사용할 수 있어요.

  • 테이블에 정형 타입 열을 정의할 수 있어요.

정형 타입 열은 최대 1000개의 하위 열(sub-columns)을 지원해요.

Apache Iceberg™ 테이블에서, Apache Iceberg™ 데이터 타입 list, struct, map은 Snowflake의 정형 ARRAY, 정형 OBJECT, MAP 타입에 해당해요.

  • 테이블의 정형 타입 열에서 데이터에 접근할 때 정형 타입을 사용해요.

  • 반정형 ARRAY, OBJECT, VARIANT 값을 해당 정형 타입으로 캐스팅할 수 있어요(예: ARRAY 값을 INTEGER 요소의 ARRAY 값으로). 정형 타입을 반정형 타입으로 캐스팅할 수도 있어요.

이 문서는 Snowflake에서 정형 타입을 사용하는 방법을 설명해요.

참고: 정형 타입은 동적 테이블(dynamic), 하이브리드 테이블(hybrid), 외부 테이블(external)에서 지원되지 않아요.

정형 타입 지정하기 (Specifying a structured type)

정형 타입 열을 정의하거나 값을 정형 타입으로 캐스팅할 때 다음 섹션에 설명된 구문을 사용해요.

  • 정형 ARRAY 타입 지정하기
  • 정형 OBJECT 타입 지정하기
  • MAP 타입 지정하기

정형 ARRAY 타입 지정하기 (Specifying a structured ARRAY type)

정형 ARRAY 타입을 지정하려면 다음 구문을 사용해요.

ARRAY( <element_type> [ NOT NULL ] )

여기서:

요소의 타입으로 정형 ARRAY, 정형 OBJECT, MAP을 지정할 수도 있어요.

참고: 표준 Snowflake 테이블(비-Iceberg) 열의 정의에서는 ARRAY 요소의 타입으로 GEOGRAPHY를 지정할 수 없어요.

Iceberg 테이블 열의 정의에서는 ARRAY 요소의 타입으로 DECFLOAT, VARIANT, 반정형 ARRAY, 반정형 OBJECT를 지정할 수 없어요.

  • NOT NULL은 ARRAY가 NULL인 요소를 담을 수 없음을 지정해요.

예를 들어 다음 문에서 SYSTEM$TYPEOF 함수가 반환하는 타입을 비교해 봐요.

  • 첫 번째 열 표현식은 반정형 ARRAY 값을 정형 ARRAY 값(NUMBER 요소의 ARRAY)으로 캐스팅해요.
  • 두 번째 열 표현식은 반정형 ARRAY 값을 지정해요.
SELECT
  SYSTEM$TYPEOF(
    [1, 2, 3]::ARRAY(NUMBER)
  ) AS structured_array,
  SYSTEM$TYPEOF(
    [1, 2, 3]
  ) AS semi_structured_array;
+-------------------------------+-----------------------+
| STRUCTURED_ARRAY              | SEMI_STRUCTURED_ARRAY |
|-------------------------------+-----------------------|
| ARRAY(NUMBER(38,0))[LOB]      | ARRAY[LOB]            |
+-------------------------------+-----------------------+

정형 OBJECT 타입 지정하기 (Specifying a structured OBJECT type)

정형 OBJECT 타입을 지정하려면 다음 구문을 사용해요.

OBJECT(
  [
    <key> <value_type> [ NOT NULL ]
    [ , <key> <value_type> [ NOT NULL ] ]
    [ , ... ]
  ]
)

여기서:

  • _key_는 OBJECT 타입의 키를 지정해요.

    • OBJECT 정의의 각 _key_는 고유해야 해요.
    • 키의 순서는 OBJECT 정의의 일부예요. 같은 키를 다른 순서로 가진 두 OBJECT 값을 비교하는 것은 허용되지 않아요. (컴파일 타임 오류가 발생해요.)
    • 키를 지정하지 않고 괄호만 지정하면(즉 OBJECT()), 결과 타입은 키가 없는 정형 OBJECT예요. 키가 없는 정형 OBJECT는 반정형 OBJECT와 달라요.
  • _value_type_은 키에 해당하는 값의 Snowflake 데이터 타입이에요.

값의 타입으로 정형 ARRAY, 정형 OBJECT, MAP을 지정할 수도 있어요.

참고: 표준 Snowflake 테이블(비-Iceberg) 열의 정의에서는 OBJECT 키에 해당하는 값의 타입으로 GEOGRAPHY를 지정할 수 없어요.

Iceberg 테이블 열의 정의에서는 OBJECT 키에 해당하는 값의 타입으로 DECFLOAT, VARIANT, 반정형 ARRAY, 반정형 OBJECT를 지정할 수 없어요.

  • NOT NULL은 키에 해당하는 값이 NULL일 수 없음을 지정해요.

예를 들어 다음 문에서 SYSTEM$TYPEOF 함수가 반환하는 타입을 비교해 봐요.

  • 첫 번째 열 표현식은 반정형 OBJECT 값을 다음 키와 값을 포함하는 정형 OBJECT 값으로 캐스팅해요.

    • NULL이 아닌 VARCHAR 값이 있는 str이라는 키.
    • NUMBER 값이 있는 num이라는 키.
  • 두 번째 열 표현식은 반정형 OBJECT 값을 지정해요.

SELECT
  SYSTEM$TYPEOF(
    {
      'str': 'test',
      'num': 1
    }::OBJECT(
      str VARCHAR NOT NULL,
      num NUMBER
    )
  ) AS structured_object,
  SYSTEM$TYPEOF(
    {
      'str': 'test',
      'num': 1
    }
  ) AS semi_structured_object;
+-----------------------------------------------------+------------------------+
| STRUCTURED_OBJECT                                   | SEMI_STRUCTURED_OBJECT |
|-----------------------------------------------------+------------------------|
| OBJECT(str VARCHAR NOT NULL, num NUMBER(38,0))[LOB] | OBJECT[LOB]            |
+-----------------------------------------------------+------------------------+

MAP 타입 지정하기 (Specifying a MAP type)

MAP 타입을 지정하려면 다음 구문을 사용해요.

MAP( <key_type> , <value_type> [ NOT NULL ] )

여기서:

  • _key_type_은 맵의 키에 대한 Snowflake 데이터 타입이에요. 키에는 다음 타입 중 하나를 사용해야 해요.

    • VARCHAR
    • scale이 0인 NUMBER

키의 타입으로 부동 소수점 데이터 타입을 사용할 수 없어요.

맵 키는 NULL일 수 없어요.

값의 타입으로 정형 ARRAY, 정형 OBJECT, MAP을 지정할 수도 있어요.

참고: 표준 Snowflake 테이블(비-Iceberg) 열의 정의에서는 MAP의 값 타입으로 GEOGRAPHY를 지정할 수 없어요.

Iceberg 테이블 열의 정의에서는 MAP의 값 타입으로 DECFLOAT, VARIANT, 반정형 ARRAY, 반정형 OBJECT를 지정할 수 없어요.

  • NOT NULL은 키에 해당하는 값이 NULL일 수 없음을 지정해요.

다음 예제는 반정형 OBJECT 값을 MAP 값으로 캐스팅하고 SYSTEM$TYPEOF 함수를 사용해 결과 값의 타입을 출력해요. 이 MAP은 VARCHAR 키를 VARCHAR 값과 연결해요.

SELECT
  SYSTEM$TYPEOF(
    {
      'a_key': 'a_val',
      'b_key': 'b_val'
    }::MAP(VARCHAR, VARCHAR)
  ) AS map_example;
+----------------------------+
| MAP_EXAMPLE                |
|----------------------------|
| MAP(VARCHAR, VARCHAR)[LOB] |
+----------------------------+

정형 타입 열이 있는 테이블 만들기 (Creating a table with a structured type column)

CREATE TABLE 명령으로 테이블을 만들 때, 정형 타입 지정하기에 설명된 구문을 사용해 정형 타입을 담는 열을 정의할 수 있어요.

다음 예제는 정형 타입 열을 지정하는 방법을 보여줘요.

  • 정형 ARRAY 열이 있는 테이블 만들기 예제
  • 정형 OBJECT 열이 있는 테이블 만들기 예제
  • MAP 열이 있는 테이블 만들기 예제

정형 ARRAY 열이 있는 테이블 만들기 예제 (Example of creating a table with a structured ARRAY column)

다음 문은 정형 ARRAY용 열이 있는 테이블을 만들어요.

CREATE TABLE my_table_with_structured_array_column (
  numeric_array ARRAY(NUMBER)
);

다음 문은 테이블에 행을 삽입해요.

INSERT INTO my_table_with_structured_array_column SELECT
  [10, 20, 30]::ARRAY(NUMBER);

다음 사항을 유의하세요.

  • 예제가 삽입할 값에 ARRAY 상수를 사용하므로, 예제는 VALUES 절이 아니라 쿼리(SELECT)를 사용해요.

VALUES 절은 [OBJECT 상수, ARRAY 상수, 그리고 OBJECT_CONSTRUCT, ARRAY_CONSTRUCT 같은 일부 함수를 지원하지 않습니다](/sql-reference/sql/insert#label-insert-command-usage-notes).

  • ARRAY 상수는 반정형 ARRAY(정형 ARRAY가 아님)를 지정하므로, 결과 반정형 ARRAY를 정형 ARRAY로 캐스팅해야 해요.

정형 OBJECT 열이 있는 테이블 만들기 예제 (Example of creating a table with a structured OBJECT column)

다음 문은 정형 OBJECT용 열이 있는 테이블을 만들어요.

CREATE TABLE customer (
  c_id VARCHAR,
  c_name VARCHAR,
  c_address OBJECT(
    state VARCHAR,
    city VARCHAR,
    street VARCHAR,
    zip_code NUMBER
  )
);

다음 문은 테이블에 행을 삽입해요.

INSERT INTO customer SELECT
  '1',
  'customer_name',
  {
    'state': 'CA',
    'city': 'San Mateo',
    'street': '450 Concar Drive',
    'zip_code': 94402
  }::OBJECT(
    state VARCHAR,
    city VARCHAR,
    street VARCHAR,
    zip_code NUMBER
  );

다음 사항을 유의하세요.

  • 예제가 삽입할 값에 OBJECT 상수를 사용하므로, 예제는 VALUES 절이 아니라 쿼리(SELECT)를 사용해요.

VALUES 절은 [OBJECT 상수, ARRAY 상수, 그리고 OBJECT_CONSTRUCT, ARRAY_CONSTRUCT 같은 일부 함수를 지원하지 않습니다](/sql-reference/sql/insert#label-insert-command-usage-notes).

  • OBJECT 상수는 반정형 OBJECT(정형 OBJECT가 아님)를 지정하므로, 결과 반정형 OBJECT를 정형 OBJECT로 캐스팅해야 해요.

MAP 열이 있는 테이블 만들기 예제 (Example of creating a table with a MAP column)

다음 문은 MAP용 열이 있는 테이블을 만들어요.

CREATE OR REPLACE TABLE my_table_with_map_column(my_map MAP(VARCHAR, VARCHAR));

다음 문은 테이블에 행을 삽입해요.

INSERT INTO my_table_with_map_column SELECT
  {'key123': 'value123'}::MAP(VARCHAR, VARCHAR);

다음 사항을 유의하세요.

  • 예제가 삽입할 값에 OBJECT 상수를 사용하므로, 예제는 VALUES 절이 아니라 쿼리(SELECT)를 사용해요.

VALUES 절은 [OBJECT 상수, ARRAY 상수, 그리고 OBJECT_CONSTRUCT, ARRAY_CONSTRUCT 같은 일부 함수를 지원하지 않습니다](/sql-reference/sql/insert#label-insert-command-usage-notes).

  • OBJECT 상수는 반정형 OBJECT(MAP이 아님)를 지정하므로, 결과 반정형 OBJECT를 MAP으로 캐스팅해야 해요.

정형 타입 열 추가하기 (Adding a structured type column)

정형 타입을 담는 열을 추가하려면 ALTER TABLE … ADD COLUMN을 정형 타입 지정하기에 설명된 구문과 함께 사용해요. 예를 들어:

ALTER TABLE customer ADD COLUMN phone ARRAY(VARCHAR);

정형 타입 열 삭제 및 이름 변경 (Dropping and renaming structured type columns)

정형 타입 열을 삭제하거나 이름을 바꾸려면 ALTER TABLE … DROP COLUMNALTER TABLE … RENAME COLUMN을 사용할 수 있어요 (반정형 객체가 있는 열처럼).

반정형 타입에서 정형 타입 사용하기 (Using structured types in semi-structured types)

VARIANT, 반정형 OBJECT, 반정형 ARRAY 값에서 MAP, 정형 OBJECT, 정형 ARRAY 값을 사용할 수 없어요. 다음 상황에서 오류가 발생해요.

정형 및 반정형 타입 변환하기 (Converting structured and semi-structured types)

다음 표는 정형 OBJECT, 정형 ARRAY, MAP 값을 반정형 OBJECT, ARRAY, VARIANT 값으로(및 그 반대로) 변환하는 규칙을 요약해요.

소스 데이터 타입 대상 데이터 타입 Castable Coercible
반정형 ARRAY 정형 ARRAY
반정형 OBJECT 정형 OBJECT / MAP
반정형 VARIANT 정형 ARRAY / 정형 OBJECT / MAP
정형 ARRAY 반정형 ARRAY
정형 OBJECT / MAP 반정형 OBJECT
정형 ARRAY / 정형 OBJECT / MAP 반정형 VARIANT

다음 섹션은 이 규칙을 더 자세히 설명해요.

  • 반정형 타입을 정형 타입으로 명시적으로 캐스팅하기
  • 정형 타입을 반정형 타입으로 명시적으로 캐스팅하기
  • 값 암시적 캐스팅(강제 변환)
  • 한 정형 타입에서 다른 정형 타입으로 캐스팅

반정형 타입을 정형 타입으로 명시적으로 캐스팅하기 (Explicitly casting a semi-structured type to a structured type)

반정형 타입의 값을 정형 타입의 값으로 명시적으로 캐스팅하려면 CAST 함수를 호출하거나 :: 연산자를 사용할 수 있어요.

참고: TRY_CAST는 정형 타입에서 지원되지 않아요.

다음 반정형 타입의 값만 해당 정형 타입의 값으로 캐스팅할 수 있으며, 그 외에는 런타임 오류가 발생해요.

반정형 타입 캐스팅할 수 있는 정형 타입
ARRAY 정형 ARRAY
OBJECT MAP 또는 정형 OBJECT
VARIANT MAP 또는 정형 ARRAY 또는 OBJECT

다음 섹션은 타입이 캐스팅되는 방법에 대한 더 자세한 내용을 제공해요.

  • 반정형 ARRAY 및 VARIANT 값을 정형 ARRAY 값으로 캐스팅하기
  • 반정형 OBJECT 및 VARIANT 값을 정형 OBJECT 값으로 캐스팅하기
  • 반정형 OBJECT 및 VARIANT 값을 MAP 값으로 캐스팅하기

반정형 ARRAY 및 VARIANT 값을 정형 ARRAY 값으로 캐스팅하기 (Casting semi-structured ARRAY and VARIANT values to structured ARRAY values)

다음 단계는 반정형 ARRAY 또는 VARIANT 값을 NUMBER 요소의 ARRAY 값으로 캐스팅하는 방법을 보여줘요.

SELECT
  SYSTEM$TYPEOF(
    CAST ([1,2,3] AS ARRAY(NUMBER))
  ) AS array_cast_type,
  SYSTEM$TYPEOF(
    CAST ([1,2,3]::VARIANT AS ARRAY(NUMBER))
  ) AS variant_cast_type;

또는:

SELECT
  SYSTEM$TYPEOF(
    [1,2,3]::ARRAY(NUMBER)
  ) AS array_cast_type,
  SYSTEM$TYPEOF(
    [1,2,3]::VARIANT::ARRAY(NUMBER)
  ) AS variant_cast_type;
+--------------------------+--------------------------+
| ARRAY_CAST_TYPE          | VARIANT_CAST_TYPE        |
|--------------------------+--------------------------|
| ARRAY(NUMBER(38,0))[LOB] | ARRAY(NUMBER(38,0))[LOB] |
+--------------------------+--------------------------+

반정형 ARRAY 또는 VARIANT 값을 정형 ARRAY 값으로 캐스팅할 때 다음에 유의하세요.

  • ARRAY 값의 각 요소는 ARRAY의 지정된 타입으로 캐스팅돼요.

ARRAY 열을 ARRAY(VARCHAR)로 캐스팅하면 각 값이 VARCHAR 값으로 변환돼요.

SELECT
  CAST ([1,2,3] AS ARRAY(VARCHAR)) AS varchar_array,
  SYSTEM$TYPEOF(varchar_array) AS array_cast_type;
+---------------+---------------------+
| VARCHAR_ARRAY | ARRAY_CAST_TYPE     |
|---------------+---------------------|
| [             | ARRAY(VARCHAR)[LOB] |
|   "1",        |                     |
|   "2",        |                     |
|   "3"         |                     |
| ]             |                     |
+---------------+---------------------+
  • 요소를 지정된 타입으로 캐스팅할 수 없으면(예: ['a', 'b', 'c']를 ARRAY(NUMBER)로 캐스팅), 캐스팅이 실패해요.

  • ARRAY 값에 NULL 요소가 있고 ARRAY 타입이 NOT NULL을 지정하면(예: [1, NULL, 3]을 ARRAY(NUMBER NOT NULL)로 캐스팅), 캐스팅이 실패해요.

  • 대상 요소 타입이 JSON null을 지원하지 않으면(즉 대상 타입이 반정형 ARRAY, OBJECT, VARIANT가 아니면) JSON null 값인 요소는 NULL로 변환돼요.

예를 들어 ARRAY(NUMBER)로 캐스팅하면 NUMBER는 JSON null을 지원하지 않으므로 JSON null 값은 NULL로 변환돼요.

반면 ARRAY(VARIANT)로 캐스팅하면 VARIANT는 JSON null을 지원하므로 JSON null 값은 NULL로 변환되지 않아요.

반정형 OBJECT 및 VARIANT 값을 정형 OBJECT 값으로 캐스팅하기 (Casting semi-structured OBJECT and VARIANT values to structured OBJECT values)

다음 단계는 반정형 OBJECT 또는 VARIANT 값을 citystate 키-값 쌍(VARCHAR 값)을 포함하는 정형 OBJECT 값으로 캐스팅하는 방법을 보여줘요.

SELECT
  SYSTEM$TYPEOF(
    CAST ({'city':'San Mateo','state':'CA'} AS OBJECT(city VARCHAR, state VARCHAR))
  ) AS object_cast_type,
  SYSTEM$TYPEOF(
    CAST ({'city':'San Mateo','state':'CA'}::VARIANT AS OBJECT(city VARCHAR, state VARCHAR))
  ) AS variant_cast_type;

또는:

SELECT
  SYSTEM$TYPEOF(
     {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  ) AS object_cast_type,
  SYSTEM$TYPEOF(
     {'city':'San Mateo','state':'CA'}::VARIANT::OBJECT(city VARCHAR, state VARCHAR)
  ) AS variant_cast_type;
+------------------------------------------+------------------------------------------+
| OBJECT_CAST_TYPE                         | VARIANT_CAST_TYPE                        |
|------------------------------------------+------------------------------------------|
| OBJECT(city VARCHAR, state VARCHAR)[LOB] | OBJECT(city VARCHAR, state VARCHAR)[LOB] |
+------------------------------------------+------------------------------------------+

반정형 OBJECT 또는 VARIANT 값을 정형 OBJECT 값으로 캐스팅할 때 다음에 유의하세요.

  • OBJECT 값은 OBJECT 타입에 지정되지 않은 추가 키를 담을 수 없어요.

추가 키가 있으면 캐스팅이 실패해요.

  • OBJECT 값에 OBJECT 타입에 지정된 키가 빠져 있으면 캐스팅이 실패해요.

  • OBJECT 값의 각 키 값은 해당 키에 지정된 타입으로 변환돼요.

값을 지정된 타입으로 캐스팅할 수 없으면 캐스팅이 실패해요.

  • 대상 값 타입이 JSON null을 지원하지 않으면(즉 대상 타입이 반정형 ARRAY, OBJECT, VARIANT가 아니면) 키의 값이 JSON null 값이면 NULL로 변환돼요.

예를 들어 OBJECT(city VARCHAR)로 캐스팅하면 VARCHAR는 JSON null을 지원하지 않으므로 JSON null 값은 NULL로 변환돼요.

반면 OBJECT(city VARIANT)로 캐스팅하면 VARIANT는 JSON null을 지원하므로 JSON null 값은 NULL로 변환되지 않아요.

반정형 OBJECT 및 VARIANT 값을 MAP 값으로 캐스팅하기 (Casting semi-structured OBJECT and VARIANT values to MAP values)

다음 문은 반정형 OBJECT 또는 VARIANT 값을 VARCHAR 키를 VARCHAR 값과 연결하는 MAP 값으로 캐스팅하는 방법을 보여줘요.

SELECT
  SYSTEM$TYPEOF(
    CAST ({'my_key':'my_value'} AS MAP(VARCHAR, VARCHAR))
  ) AS map_cast_type,
  SYSTEM$TYPEOF(
    CAST ({'my_key':'my_value'} AS MAP(VARCHAR, VARCHAR))
  ) AS variant_cast_type;

또는:

SELECT
  SYSTEM$TYPEOF(
    {'my_key':'my_value'}::MAP(VARCHAR, VARCHAR)
  ) AS map_cast_type,
  SYSTEM$TYPEOF(
    {'my_key':'my_value'}::VARIANT::MAP(VARCHAR, VARCHAR)
  ) AS variant_cast_type;
+----------------------------+----------------------------+
| MAP_CAST_TYPE              | VARIANT_CAST_TYPE          |
|----------------------------+----------------------------|
| MAP(VARCHAR, VARCHAR)[LOB] | MAP(VARCHAR, VARCHAR)[LOB] |
+----------------------------+----------------------------+

반정형 OBJECT 또는 VARIANT 값을 MAP 값으로 캐스팅할 때 다음에 유의하세요.

  • 키와 값이 지정된 타입과 일치하지 않으면, 키와 값은 지정된 타입으로 변환돼요.

  • 키와 값을 지정된 타입으로 캐스팅할 수 없으면 캐스팅이 실패해요.

  • 대상 값 타입이 JSON null을 지원하지 않으면(즉 대상 타입이 반정형 ARRAY, OBJECT, VARIANT가 아니면) 키의 값이 JSON null 값이면 NULL로 변환돼요.

예를 들어 MAP(VARCHAR, VARCHAR)로 캐스팅하면 VARCHAR는 JSON null을 지원하지 않으므로 JSON null 값은 NULL로 변환돼요.

반면 MAP(VARCHAR, VARIANT)로 캐스팅하면 VARIANT는 JSON null을 지원하므로 JSON null 값은 NULL로 변환되지 않아요.

정형 타입을 반정형 타입으로 명시적으로 캐스팅하기 (Explicitly casting a structured type to a semi-structured type)

정형 타입의 값을 반정형 타입의 값으로 명시적으로 캐스팅하려면 CAST 함수를 호출하거나 :: 연산자를 사용하거나, 변환 함수 중 하나(예: TO_ARRAY, TO_OBJECT, TO_VARIANT)를 호출할 수 있어요.

참고: TRY_CAST는 정형 타입에서 지원되지 않아요.

정형 타입 캐스팅할 수 있는 반정형 타입
정형 ARRAY ARRAY
MAP 또는 정형 OBJECT OBJECT
MAP, 정형 ARRAY, 또는 정형 OBJECT VARIANT

예를 들어:

  • col_structured_array가 ARRAY(VARCHAR) 타입이면:

    • CAST(col_structured_array AS ARRAY)는 반정형 ARRAY 값을 반환해요.
    • CAST(col_structured_array AS VARIANT)는 반정형 ARRAY 값을 담는 VARIANT 값을 반환해요.
  • col_structured_object가 OBJECT(name VARCHAR, state VARCHAR) 타입이면:

    • CAST(col_structured_object AS OBJECT)는 반정형 OBJECT 값을 반환해요.
    • CAST(col_structured_object AS VARIANT)는 반정형 OBJECT 값을 담는 VARIANT 값을 반환해요.
  • col_map이 MAP(VARCHAR, VARCHAR) 타입이면:

    • CAST(col_map AS OBJECT)는 반정형 OBJECT 값을 반환해요.
    • CAST(col_map AS VARIANT)는 반정형 OBJECT 값을 담는 VARIANT 값을 반환해요.

다음에 유의하세요.

  • 반정형 OBJECT 값으로 캐스팅할 때, 정형 OBJECT 값의 키 순서는 보존되지 않아요.

  • 정형 OBJECT 또는 MAP 값을 반정형 OBJECT 또는 VARIANT 값으로 캐스팅할 때, NULL 값은 JSON null 값으로 변환돼요.

정형 ARRAY 값을 VARIANT 값으로 캐스팅하면 NULL 값은 그대로 보존돼요.

SELECT [1,2,NULL,3]::ARRAY(INTEGER)::VARIANT;
+---------------------------------------+
| [1,2,NULL,3]::ARRAY(INTEGER)::VARIANT |
|---------------------------------------|
| [                                     |
|   1,                                  |
|   2,                                  |
|   undefined,                          |
|   3                                   |
| ]                                     |
+---------------------------------------+
  • 키에 NUMBER 타입을 사용하는 MAP 값을 캐스팅하면, 반환된 OBJECT 값에서 MAP 키는 문자열로 변환돼요.

값 암시적 캐스팅(강제 변환) (Implicit casting a value (coercion))

다음 규칙은 한 정형 타입의 값에서 다른 정형 타입의 값으로의 암시적 캐스팅(강제 변환)에 적용돼요.

  • 두 기본 타입이 같으면 정형 타입 값은 다른 정형 타입 값으로 강제 변환될 수 있어요.

    • 한 타입의 ARRAY 값은, 첫 번째 요소 타입이 두 번째 요소 타입으로 강제 변환 가능하다면, 다른 타입의 ARRAY 값으로 강제 변환될 수 있어요.

요소 타입은 다음 중 한 경우에 다른 요소 타입으로 강제 변환될 수 있어요.

  • 두 타입 모두 숫자(numeric)인 경우. 다음 경우가 지원돼요.

    • 둘 다 같은 숫자 타입이지만 정밀도 및/또는 scale이 다를 수 있음.
    • NUMBER를 FLOAT로 강제 변환(및 그 반대).
  • 두 타입 모두 타임스탬프(timestamp)인 경우. 다음 경우가 지원돼요.

    • 둘 다 같은 타입이지만 정밀도가 다를 수 있음.
    • TIMESTAMP_LTZ를 TIMESTAMP_TZ로 강제 변환(및 그 반대).

예를 들어:

  • ARRAY(NUMBER) 값은 ARRAY(DOUBLE) 값으로 강제 변환될 수 있어요.

  • ARRAY(DATE) 값은 ARRAY(NUMBER) 값으로 강제 변환될 수 없어요.

  • 한 타입 정의의 OBJECT 값은, 다음이 모두 참일 때만 다른 타입 정의의 OBJECT 값으로 강제 변환될 수 있어요.

    • 두 OBJECT 타입의 키 수가 같다.
    • 두 OBJECT 타입이 키에 같은 이름을 사용한다.
    • 두 OBJECT 타입의 키 순서가 같다.
    • 한 OBJECT 타입의 각 값 타입이 다른 OBJECT 타입의 해당 값 타입으로 강제 변환될 수 있다.

정형 ARRAY 값의 요소 타입의 경우와 마찬가지로, 다음 경우에만 한 값 타입을 다른 타입으로 강제 변환할 수 있어요.

  • 두 타입 모두 숫자(numeric)인 경우. 다음 경우가 지원돼요.

    • 둘 다 같은 숫자 타입이지만 정밀도 및/또는 scale이 다를 수 있음.
    • NUMBER를 FLOAT로 강제 변환(및 그 반대).
  • 두 타입 모두 타임스탬프(timestamp)인 경우. 다음 경우가 지원돼요.

    • 둘 다 같은 타입이지만 정밀도가 다를 수 있음.
    • TIMESTAMP_LTZ를 TIMESTAMP_TZ로 강제 변환(및 그 반대).

예를 들어:

  • OBJECT(city VARCHAR, zipcode NUMBER) 값은 OBJECT(city VARCHAR, zipcode DOUBLE) 값으로 강제 변환될 수 있어요.

  • OBJECT(city VARCHAR, zipcode NUMBER) 값은 OBJECT(city VARCHAR, zipcode DATE) 값으로 강제 변환될 수 없어요.

  • 한 값 타입의 MAP 값은, 다음 경우에 다른 값 타입의 MAP 값으로 강제 변환될 수 있어요.

    • 두 값 타입 모두 숫자(numeric)인 경우. 다음 경우가 지원돼요.

      • 둘 다 같은 숫자 타입이지만 정밀도 및/또는 scale이 다를 수 있음.
      • NUMBER를 FLOAT로 강제 변환(및 그 반대).
    • 두 값 타입 모두 타임스탬프(timestamp)인 경우. 다음 경우가 지원돼요.

      • 둘 다 같은 타입이지만 정밀도가 다를 수 있음.
      • TIMESTAMP_LTZ를 TIMESTAMP_TZ로 강제 변환(및 그 반대).

예를 들어 MAP(VARCHAR, NUMBER) 값은 MAP(VARCHAR, DOUBLE) 값으로 강제 변환될 수 있어요.

  • 한 키 타입의 MAP 값은, 두 키 타입이 정밀도만 다른 같은 정수 NUMERIC 타입을 사용할 때 다른 키 타입의 MAP 값으로 강제 변환될 수 있어요.

예를 들어 MAP(VARCHAR, NUMBER) 값은 MAP(NUMBER, NUMBER) 값으로 강제 변환될 수 없어요.

  • 정형 타입 값은 반정형 값으로 강제 변환될 수 없어요 (및 그 반대).

  • VARCHAR 값은 정형 타입 값으로 강제 변환될 수 없어요.

한 정형 타입에서 다른 정형 타입으로 캐스팅하기 (Casting from one structured type to another)

CAST 함수를 호출하거나 :: 연산자를 사용해 한 정형 타입의 값에서 다른 정형 타입의 값으로 캐스팅할 수 있어요. 다음 정형 타입으로/으로부터 값을 캐스팅할 수 있어요.

  • 정형 ARRAY의 경우:

한 타입의 ARRAY 값을 다른 타입의 ARRAY 값으로 캐스팅할 수 있어요.

  • 정형 OBJECT의 경우:

    • 캐스트를 사용해 OBJECT 값의 키-값 쌍 순서를 바꿀 수 있어요.
    • 캐스트를 사용해 OBJECT 값의 키 이름을 바꿀 수 있어요.
    • 캐스트를 사용해 OBJECT 값에 키를 추가할 수 있어요.
    • 정형 OBJECT 값을 MAP 값으로 캐스팅할 수 있어요.
  • MAP 값의 경우:

    • 특정 타입의 키와 값을 가진 MAP 값을 다른 타입의 키와 값을 가진 MAP 값으로 캐스팅할 수 있어요.
    • MAP 값을 정형 OBJECT 값으로 캐스팅할 수 있어요.

참고: TRY_CAST는 정형 타입에서 지원되지 않아요.

값을 한 타입에서 다른 타입으로 캐스팅할 수 없으면 캐스팅이 실패해요. 예를 들어 ARRAY(BOOLEAN) 값을 ARRAY(DATE) 값으로 캐스팅하려 하면 실패해요.

예제: 한 타입의 ARRAY 값에서 다른 타입으로 캐스팅 (Example: Casting from one type of ARRAY value to another)

다음 예제는 ARRAY(NUMBER) 값을 ARRAY(VARCHAR) 값으로 캐스팅해요.

SELECT CAST(
  CAST([1,2,3] AS ARRAY(NUMBER))
  AS ARRAY(VARCHAR)) AS cast_array;
+------------+
| CAST_ARRAY |
|------------|
| [          |
|   "1",     |
|   "2",     |
|   "3"      |
| ]          |
+------------+

예제: OBJECT 값의 키-값 쌍 순서 바꾸기 (Example: Changing the order of key-value pairs in an OBJECT value)

다음 예제는 정형 OBJECT 값의 키-값 쌍 순서를 바꿔요.

SELECT CAST(
  {'city': 'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(state VARCHAR, city VARCHAR)) AS object_value_order;
+-----------------------+
| OBJECT_VALUE_ORDER    |
|-----------------------|
| {                     |
|   "state": "CA",      |
|   "city": "San Mateo" |
| }                     |
+-----------------------+

예제: OBJECT 값의 키 이름 바꾸기 (Example: Changing the key names in an OBJECT value)

정형 OBJECT 값의 키 이름을 바꾸려면 CAST 끝에 RENAME FIELDS 키워드를 지정해요. 예를 들어:

SELECT CAST({'city':'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(city_name VARCHAR, state_name VARCHAR) RENAME FIELDS) AS object_value_key_names;
+-----------------------------+
| OBJECT_VALUE_KEY_NAMES      |
|-----------------------------|
| {                           |
|   "city_name": "San Mateo", |
|   "state_name": "CA"        |
| }                           |
+-----------------------------+

예제: OBJECT 값에 키 추가하기 (Example: Adding keys to an OBJECT value)

캐스팅하는 타입에 원래 정형 OBJECT 값에 없는 추가 키-값 쌍이 있다면, CAST 끝에 ADD FIELDS 키워드를 지정해요. 예를 들어:

SELECT CAST({'city':'San Mateo','state': 'CA'}::OBJECT(city VARCHAR, state VARCHAR)
  AS OBJECT(city VARCHAR, state VARCHAR, zipcode NUMBER) ADD FIELDS) AS add_fields;
+------------------------+
| ADD_FIELDS             |
|------------------------|
| {                      |
|   "city": "San Mateo", |
|   "state": "CA",       |
|   "zipcode": null      |
| }                      |
+------------------------+

새로 추가된 키의 값은 NULL로 설정돼요. 이 키에 값을 할당하려면 OBJECT_INSERT 함수를 호출하세요.

정형 ARRAY, 정형 OBJECT, MAP 값 구성하기 (Constructing structured ARRAY, structured OBJECT, and MAP values)

다음 섹션은 정형 ARRAY, 정형 OBJECT, MAP 값을 구성하는 방법을 설명해요.

  • SQL 함수를 사용해 정형 ARRAY와 OBJECT 값 구성하기
  • ARRAY와 OBJECT 상수를 사용해 정형 ARRAY와 OBJECT 값 구성하기
  • MAP 값 구성하기

SQL 함수를 사용해 정형 ARRAY와 OBJECT 값 구성하기 (Using SQL functions to construct structured ARRAY and OBJECT values)

정형 ARRAY 또는 OBJECT 값을 직접 구성하려면 다음 함수를 사용해요.

예를 들어:

SELECT ARRAY_CONSTRUCT_STRUCTURED(10, 20, 30);
SELECT OBJECT_CONSTRUCT_KEEP_NULL_STRUCTURED(
  'oname', 'abc',
  'created_date', NULL::DATE
);

반정형 ARRAY 또는 OBJECT 값을 구성하고 결과를 정형 타입으로 명시적으로 캐스팅할 수도 있어요. 다음 함수는 반정형 ARRAY 값을 구성해요.

다음 함수는 반정형 OBJECT 값을 구성해요.

예를 들어:

SELECT ARRAY_CONSTRUCT(10, 20, 30)::ARRAY(NUMBER);
SELECT OBJECT_CONSTRUCT(
  'oname', 'abc',
  'created_date', '2020-01-18'::DATE
)::OBJECT(
  oname VARCHAR,
  created_date DATE
);

자세한 내용은 반정형 타입을 정형 타입으로 명시적으로 캐스팅하기를 참조하세요.

참고: 정형 ARRAY, 정형 OBJECT, MAP 값을 반정형 구성 함수(예: ARRAY_CONSTRUCT, OBJECT_CONSTRUCT)에 전달할 수 없어요. 그렇게 하면 정형 타입이 반정형 타입으로 암시적으로 캐스팅되는데, 값 암시적 캐스팅(강제 변환)에 언급된 대로 이는 허용되지 않아요. 정형 입력에서 정형 값을 구성하려면 대신 ARRAY_CONSTRUCT_STRUCTURED 또는 OBJECT_CONSTRUCT_KEEP_NULL_STRUCTURED를 사용하세요.

ARRAY와 OBJECT 상수를 사용해 정형 ARRAY와 OBJECT 값 구성하기 (Using ARRAY and OBJECT constants to construct structured ARRAY and OBJECT values)

ARRAY 상수OBJECT 상수를 지정하면 반정형 ARRAY 또는 OBJECT 값을 지정하는 것이에요.

정형 ARRAY 또는 OBJECT 값을 구성하려면 표현식을 명시적으로 캐스팅해야 해요. 예를 들어:

SELECT [10, 20, 30]::ARRAY(NUMBER);
SELECT {
  'oname': 'abc',
  'created_date': '2020-01-18'::DATE
}::OBJECT(
  oname VARCHAR,
  created_date DATE
);

자세한 내용은 반정형 타입을 정형 타입으로 명시적으로 캐스팅하기를 참조하세요.

MAP 값 구성하기 (Constructing a MAP value)

MAP 값을 직접 구성하려면 MAP_CONSTRUCT를 사용해요. 예를 들어 다음 문은 MAP 값 {'city'->'San Mateo','state'->'CA'}을 생성해요.

SELECT MAP_CONSTRUCT(
  'city', 'San Mateo',
  'state', 'CA'
);

반정형 OBJECT 값을 구성해 MAP 값으로 캐스팅할 수도 있어요. 예를 들어 다음 두 문은 모두 같은 MAP 값을 생성해요.

SELECT OBJECT_CONSTRUCT(
  'city', 'San Mateo',
  'state', 'CA'
)::MAP(
  VARCHAR,
  VARCHAR
);
SELECT {
  'city': 'San Mateo',
  'state': 'CA'
}::MAP(
  VARCHAR,
  VARCHAR
);

다음 문은 MAP 값 {-10->'CA',-20->'OR'}을 생성해요.

SELECT {
  '-10': 'CA',
  '-20': 'OR'
}::MAP(
  NUMBER,
  VARCHAR
);

자세한 내용은 반정형 OBJECT 및 VARIANT 값을 MAP 값으로 캐스팅하기를 참조하세요.

정형 타입 값의 키, 값, 요소 다루기 (Working with keys, values, and elements in values of structured types)

다음 섹션은 정형 타입 값에서 키, 값, 요소를 사용하는 방법을 설명해요.

  • 정형 OBJECT 값에서 키 목록 가져오기
  • MAP 값에서 키 목록 가져오기
  • 정형 타입 값에서 값과 요소에 접근하기
  • 정형 ARRAY 값의 크기 결정하기
  • MAP 값의 크기 결정하기
  • 정형 ARRAY 값에서 요소 찾기
  • MAP 값에 키가 포함되어 있는지 결정하기

정형 OBJECT 값에서 키 목록 가져오기 (Getting the list of keys from a structured OBJECT value)

정형 OBJECT 값의 키 목록을 가져오려면 OBJECT_KEYS 함수를 호출해요.

SELECT OBJECT_KEYS({'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR, state VARCHAR));

입력이 정형 OBJECT 값이면 함수는 키를 포함하는 ARRAY(VARCHAR) 값을 반환해요. 입력이 반정형 OBJECT 값이면 함수는 ARRAY 값을 반환해요.

MAP 값에서 키 목록 가져오기 (Getting the list of keys from a MAP value)

MAP 값의 키 목록을 가져오려면 MAP_KEYS 함수를 호출해요.

SELECT MAP_KEYS({'my_key':'my_value'}::MAP(VARCHAR,VARCHAR));

정형 타입 값에서 값과 요소에 접근하기 (Accessing values and elements from values of structured types)

정형 ARRAY, 정형 OBJECT, MAP 값에서 값과 요소에 접근하는 데 다음 방법을 사용할 수 있어요.

반환되는 값과 요소는 VARIANT가 아니라 정형 값에 지정된 타입을 가져요.

다음 예제는 반정형 ARRAY 값의 첫 요소와 ARRAY(VARCHAR) 값을 SYSTEM$TYPEOF 함수에 전달해 그 요소의 데이터 타입을 반환해요.

SELECT
  SYSTEM$TYPEOF(
    ARRAY_CONSTRUCT('San Mateo')[0]
  ) AS semi_structured_array_element,
  SYSTEM$TYPEOF(
    CAST(
      ARRAY_CONSTRUCT('San Mateo') AS ARRAY(VARCHAR)
    )[0]
  ) AS structured_array_element;
+-------------------------------+--------------------------+
| SEMI_STRUCTURED_ARRAY_ELEMENT | STRUCTURED_ARRAY_ELEMENT |
|-------------------------------+--------------------------|
| VARIANT[LOB]                  | VARCHAR[LOB]             |
+-------------------------------+--------------------------+

다음에 유의하세요.

  • 정형 OBJECT 값을 GET 또는 GET_IGNORE_CASE 함수에 전달할 때는 키에 상수를 지정해야 해요.

GET 함수에 MAP 또는 정형 ARRAY 값을 전달하면 상수를 지정할 필요가 없어요.

GET_IGNORE_CASE 함수에 MAP 값을 전달해도 상수를 지정할 필요가 없어요.

  • 정형 OBJECT, 정형 ARRAY, MAP 값을 GET_PATH 함수에 전달할 때는 경로 이름에 상수를 지정해야 해요.

  • 정형 OBJECT 값의 경우, 존재하지 않는 OBJECT 키나 경로를 사용하면 컴파일 타임 오류가 발생해요.

대조적으로, 반정형 OBJECT 값과 존재하지 않는 인덱스, 키, 경로를 사용하면 함수는 NULL을 반환해요.

정형 ARRAY 값의 크기 결정하기 (Determining the size of a structured ARRAY value)

정형 ARRAY 값의 크기를 결정하려면 ARRAY 값을 ARRAY_SIZE 함수에 전달해요.

SELECT ARRAY_SIZE([1,2,3]::ARRAY(NUMBER));

MAP 값의 크기 결정하기 (Determining the size of a MAP value)

MAP 값의 크기를 결정하려면 MAP 값을 MAP_SIZE 함수에 전달해요.

SELECT MAP_SIZE({'my_key':'my_value'}::MAP(VARCHAR,VARCHAR));

정형 ARRAY 값에서 요소 찾기 (Looking up elements in a structured ARRAY value)

정형 ARRAY 값에 요소가 있는지 결정하려면 ARRAY_CONTAINS 함수를 호출해요. 예를 들어:

SELECT ARRAY_CONTAINS(10, [1, 10, 100]::ARRAY(NUMBER));

정형 ARRAY 값에서 요소의 위치를 결정하려면 ARRAY_POSITION 함수를 호출해요. 예를 들어:

SELECT ARRAY_POSITION(10, [1, 10, 100]::ARRAY(NUMBER));

참고: 두 함수 모두 ARRAY 값의 타입과 비교 가능한 타입의 요소를 사용해요. 요소의 표현식을 VARIANT 값으로 캐스팅하지 마세요.

MAP 값에 키가 포함되어 있는지 결정하기 (Determining if a MAP value contains a key)

MAP 값에 키가 포함되어 있는지 결정하려면 MAP_CONTAINS_KEY 함수를 호출해요.

예를 들어:

SELECT MAP_CONTAINS_KEY('key_to_find', my_map);
SELECT MAP_CONTAINS_KEY(10, my_map);

값 비교하기 (Comparing values)

다음 섹션은 값을 비교하는 방법을 설명해요.

  • 정형 값과 반정형 값 비교하기
  • 정형 값과 다른 정형 값 비교하기
  • 두 ARRAY 값이 겹치는지 결정하기

정형 값과 반정형 값 비교하기 (Comparing structured values with semi-structured values)

정형 ARRAY, 정형 OBJECT, MAP 값을 반정형 ARRAY, OBJECT, VARIANT 값과 비교할 수 없어요.

정형 값과 다른 정형 값 비교하기 (Comparing structured values with other structured values)

같은 타입의 두 값을 비교할 수 있어요 (예: 두 정형 ARRAY 값, 두 정형 OBJECT 값, 두 MAP 값).

현재 정형 타입의 값을 비교하는 데 다음 비교 연산자가 지원돼요.

  • =
  • !=
  • <
  • <=
  • >=
  • >

동등성에 대해 두 정형 값을 비교할 때 다음에 유의하세요.

  • 한 타입을 다른 타입으로 강제 변환할 수 없으면 비교가 실패해요.
  • 숫자 키가 있는 MAP 값을 비교할 때, 키는 (VARCHAR 값이 아니라) 숫자로 비교돼요.

<, <=, >=, >로 두 정형 값을 비교할 때, 정형 값 필드는 알파벳 순서로 비교돼요. 예를 들어 다음 값은:

{'a':2,'b':1}::OBJECT(b INTEGER,a INTEGER)

다음보다 크다:

{'a':1,'b':2}::OBJECT(b INTEGER,a INTEGER)

두 ARRAY 값이 겹치는지 결정하기 (Determining if two ARRAY values overlap)

두 정형 ARRAY 값의 요소가 겹치는지 결정하려면 ARRAYS_OVERLAP 함수를 호출해요. 예를 들어:

SELECT ARRAYS_OVERLAP(numeric_array, other_numeric_array);

ARRAY 값은 비교 가능한 타입이어야 해요.

이 함수에 반정형 ARRAY 값과 정형 ARRAY 값을 전달할 수 없어요. 두 ARRAY 값은 모두 정형 또는 모두 반정형이어야 해요.

정형 타입 값 변환하기 (Transforming values of structured types)

다음 섹션은 정형 ARRAY, 정형 OBJECT, MAP 값을 변환하는 방법을 설명해요.

  • 정형 ARRAY 값 변환하기
  • 정형 OBJECT 값 변환하기
  • MAP 값 변환하기

정형 ARRAY 값 변환하기 (Transforming structured ARRAY values)

정형 ARRAY 값을 이 함수들에 전달하면 함수는 같은 타입의 정형 ARRAY 값을 반환해요.

다음 섹션은 이 함수들이 정형 ARRAY 값으로 어떻게 동작하는지 설명해요.

  • ARRAY 값에 요소를 추가하는 함수
  • 여러 ARRAY 값을 입력으로 받는 함수

ARRAY 값에 요소를 추가하는 함수 (Functions that add elements to ARRAY values)

다음 함수는 ARRAY 값에 요소를 추가해요.

이 함수들의 경우 요소의 타입은 ARRAY 값의 타입으로 강제 변환 가능해야 해요.

예를 들어 NUMBER 값은(ARRAY 값의 타입인) DOUBLE 값으로 강제 변환될 수 있으므로 다음 호출은 성공해요.

SELECT ARRAY_APPEND( [1,2]::ARRAY(DOUBLE), 3::NUMBER );

VARCHAR 값은 DOUBLE 값으로 강제 변환될 수 있으므로 다음 호출은 성공해요.

SELECT ARRAY_APPEND( [1,2]::ARRAY(DOUBLE), '3' );

DATE 값은 NUMBER 값으로 강제 변환될 수 없으므로 다음 호출은 실패해요.

SELECT ARRAY_APPEND( [1,2]::ARRAY(NUMBER), '2022-02-02'::DATE );

여러 ARRAY 값을 입력으로 받는 함수 (Functions that accept multiple ARRAY values as input)

다음 함수는 입력 인자로 여러 ARRAY 값을 받아요.

이 함수들을 호출할 때 두 인자는 모두 정형 ARRAY 값이거나 모두 반정형 ARRAY 값이어야 해요. 예를 들어 한 인자는 정형 ARRAY 값이고 다른 인자는 반정형 ARRAY 값이므로 다음 호출은 실패해요.

SELECT ARRAY_CAT( [1,2]::ARRAY(NUMBER), ['3','4'] );
SELECT ARRAY_CAT( [1,2], ['3','4']::ARRAY(VARCHAR) );

ARRAY_EXCEPT 함수는 첫 번째 인자의 ARRAY 값과 같은 타입의 ARRAY 값을 반환해요.

ARRAY_CAT과 ARRAY_INTERSECTION 함수는 두 입력 값의 타입을 모두 수용할 수 있는 타입의 ARRAY 값을 반환해요.

예를 들어 ARRAY_CAT에 대한 다음 호출은 두 개의 정형 ARRAY 값을 전달해요.

  • 첫 번째 정형 ARRAY 값은 NULL을 허용하지 않고 scale이 0인 NUMBER 값(NUMBER(38, 0))을 담아요.
  • 두 번째 정형 ARRAY 값은 NULL과 scale이 1인 NUMBER 값을 담아요.

ARRAY_CAT이 반환하는 ARRAY 값은 NULL을 허용하고 scale이 1인 NUMBER 값을 담아요.

SELECT
  ARRAY_CAT(
    [1, 2, 3]::ARRAY(NUMBER NOT NULL),
    [5.5, NULL]::ARRAY(NUMBER(2, 1))
  ) AS concatenated_array,
  SYSTEM$TYPEOF(concatenated_array);
+--------------------+-----------------------------------+
| CONCATENATED_ARRAY | SYSTEM$TYPEOF(CONCATENATED_ARRAY) |
|--------------------+-----------------------------------|
| [                  | ARRAY(NUMBER(38,1))[LOB]          |
|   1,               |                                   |
|   2,               |                                   |
|   3,               |                                   |
|   5.5,             |                                   |
|   undefined        |                                   |
| ]                  |                                   |
+--------------------+-----------------------------------+

ARRAY_CAT 함수의 경우, 두 번째 인자의 ARRAY 값은 첫 번째 인자의 타입으로 강제 변환 가능해야 해요.

ARRAY_EXCEPT과 ARRAY_INTERSECTION 함수의 경우, 두 번째 인자의 ARRAY 값은 첫 번째 인자의 ARRAY 값과 비교 가능해야 해요.

예를 들어 ARRAY(NUMBER) 값은 ARRAY(DOUBLE) 값과 비교 가능하므로 다음 호출은 성공해요.

SELECT ARRAY_EXCEPT( [1,2]::ARRAY(NUMBER), [2,3]::ARRAY(DOUBLE) );

ARRAY(NUMBER) 값은 ARRAY(VARCHAR) 값과 비교 가능하지 않으므로 다음 호출은 실패해요.

SELECT ARRAY_EXCEPT( [1,2]::ARRAY(NUMBER), ['2','3']::ARRAY(VARCHAR) );

정형 OBJECT 값 변환하기 (Transforming structured OBJECT values)

다음 섹션은 다른 OBJECT 값에서 변환된 정형 OBJECT 값을 반환하는 방법을 설명해요.

  • 키-값 쌍 제거하기
  • 키-값 쌍 삽입 및 값 업데이트하기
  • 기존 OBJECT에서 키-값 쌍 선택하기

키-값 쌍의 순서를 바꾸거나, 키 이름을 바꾸거나, 값을 지정하지 않고 키를 추가하려면 CAST 함수 또는 :: 연산자를 사용해요. 자세한 내용은 한 정형 타입에서 다른 정형 타입으로 캐스팅하기를 참조하세요.

키-값 쌍 제거하기 (Removing key-value pairs)

특정 키-값 쌍이 제거된 기존 OBJECT 값의 키-값 쌍을 담는 새 OBJECT 값을 반환하려면 OBJECT_DELETE 함수를 호출해요.

이 함수를 호출할 때 다음에 유의하세요.

  • 키인 인자에는 상수를 지정해야 해요.

  • 지정된 키가 OBJECT 타입 정의의 일부가 아니면 호출이 실패해요. 예를 들어 OBJECT 값에 지정된 zip_code 키가 없으므로 다음 호출은 실패해요.

SELECT OBJECT_DELETE( {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR), 'zip_code' );
093201 (23001): Function OBJECT_DELETE: expected structured object to contain field zip_code but it did not.
  • 이 함수는 정형 OBJECT 값을 반환해요. OBJECT 값의 타입은 삭제된 키를 제외해요. 예를 들어 city 키를 제거한다고 해 봐요.
SELECT
  OBJECT_DELETE(
 {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
 'city'
  ) AS new_object,
  SYSTEM$TYPEOF(new_object);

이 함수는 city 키를 포함하지 않는 OBJECT(state VARCHAR) 타입의 OBJECT 값을 반환해요.

+-----------------+----------------------------+
| NEW_OBJECT      | SYSTEM$TYPEOF(NEW_OBJECT)  |
|-----------------+----------------------------|
| {               | OBJECT(state VARCHAR)[LOB] |
|   "state": "CA" |                            |
| }               |                            |
+-----------------+----------------------------+
  • 함수가 OBJECT 값에서 모든 키를 제거하면, 함수는 OBJECT() 타입의 빈 정형 OBJECT 값을 반환해요.
SELECT
  OBJECT_DELETE(
 {'state':'CA'}::OBJECT(state VARCHAR),
 'state'
  ) AS new_object,
  SYSTEM$TYPEOF(new_object);
+------------+---------------------------+
| NEW_OBJECT | SYSTEM$TYPEOF(NEW_OBJECT) |
|------------+---------------------------|
| {}         | OBJECT()[LOB]             |
+------------+---------------------------+

정형 OBJECT 값의 타입이 키-값 쌍을 포함하면, 그 쌍의 이름과 타입이 타입의 괄호 안에 포함돼요(예: OBJECT(city VARCHAR)). 빈 정형 OBJECT 값은 키-값 쌍을 포함하지 않으므로 괄호는 비어 있어요.

키-값 쌍 삽입 및 값 업데이트하기 (Inserting key-value pairs and updating values)

추가 키-값 쌍이나 키의 새 값이 있는 기존 OBJECT 값의 키-값 쌍을 담는 새 OBJECT 값을 반환하려면 OBJECT_INSERT 함수를 호출해요.

이 함수를 호출할 때 다음에 유의하세요.

  • 키인 인자에는 상수를 지정해야 해요.

  • <updateFlag> 인자가 FALSE일 때(새 키-값 쌍을 삽입할 때):

    • OBJECT 값에 이미 존재하는 키를 지정하면 오류가 발생해요.
SELECT OBJECT_INSERT(
  {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
  'city',
  'San Jose',
  false
);
093202 (23001): Function OBJECT_INSERT:
  expected structured object to not contain field city but it did.
* 이 함수는 정형 OBJECT 값을 반환해요. OBJECT 값의 타입은 새로 삽입된 키를 포함해요. 예를 들어 VARCHAR 값 `94402`로 `zipcode` 키를 추가한다고 해 봐요.
SELECT
  OBJECT_INSERT(
    {'city':'San Mateo','state':'CA'}::OBJECT(city VARCHAR,state VARCHAR),
    'zip_code',
    94402::VARCHAR,
    false
  ) AS new_object,
  SYSTEM$TYPEOF(new_object) AS type;
+------------------------+---------------------------------------------------------------------+
| NEW_OBJECT             | TYPE                                                                |
|------------------------+---------------------------------------------------------------------|
| {                      | OBJECT(city VARCHAR, state VARCHAR, zip_code VARCHAR NOT NULL)[LOB] |
|   "city": "San Mateo", |                                                                     |
|   "state": "CA",       |                                                                     |
|   "zip_code": "94402"  |                                                                     |
| }                      |                                                                     |
+------------------------+---------------------------------------------------------------------+

삽입된 값의 타입이 OBJECT 타입 정의에 추가되는 타입을 결정해요. 이 경우 zipcode의 값은 VARCHAR로 캐스팅된 값이므로 zipcode의 타입은 VARCHAR예요.

  • <updateFlag> 인자가 TRUE일 때(기존 키-값 쌍을 대체할 때):

    • OBJECT 값에 존재하지 않는 키를 지정하면 오류가 발생해요.
    • 이 함수는 같은 타입의 정형 OBJECT 값을 반환해요.
    • 삽입된 값의 타입은 기존 키의 타입으로 강제 변환돼요.

기존 OBJECT에서 키-값 쌍 선택하기 (Selecting key-value pairs from an existing OBJECT)

기존 OBJECT 값에서 선택된 키-값 쌍을 담는 새 OBJECT 값을 반환하려면 OBJECT_PICK 함수를 호출해요.

이 함수를 호출할 때 다음에 유의하세요.

  • 키인 인자에는 상수를 지정해야 해요.

  • 두 번째 인자로 키의 ARRAY를 전달할 수 없어요. 각 키를 별도 인자로 지정해야 해요.

  • 이 함수는 정형 OBJECT 값을 반환해요. OBJECT 값의 타입은 지정된 순서대로 키를 포함해요.

예를 들어 statecity 키를 그 순서대로 선택한다고 해 봐요.

SELECT
  OBJECT_PICK(
 {'city':'San Mateo','state':'CA','zip_code':94402}::OBJECT(city VARCHAR,state VARCHAR,zip_code DOUBLE),
 'state',
 'city') AS new_object,
  SYSTEM$TYPEOF(new_object);

이 함수는 OBJECT(state VARCHAR, city VARCHAR) 타입의 OBJECT 값을 반환해요.

+-----------------------+------------------------------------------+
| NEW_OBJECT            | SYSTEM$TYPEOF(NEW_OBJECT)                |
|-----------------------+------------------------------------------|
| {                     | OBJECT(state VARCHAR, city VARCHAR)[LOB] |
|   "state": "CA",      |                                          |
|   "city": "San Mateo" |                                          |
| }                     |                                          |
+-----------------------+------------------------------------------+

MAP 값 변환하기 (Transforming MAP values)

MAP 값을 변환하려면 다음 함수를 사용해요.

정형 타입으로 작업하기 (Working with structured types)

다음 섹션은 정형 타입의 값과 함께 다양한 SQL 함수와 집합 연산자를 사용하는 방법을 설명해요.

  • FLATTEN 함수를 정형 타입의 값과 함께 사용하기
  • PARSE_JSON 함수 사용하기
  • 집합 연산자와 CASE 표현식과 함께 정형 타입 사용하기
  • 다른 반정형 함수와 작업하기

FLATTEN 함수를 정형 타입의 값과 함께 사용하기 (Using the FLATTEN function with values of structured types)

FLATTEN 함수에 정형 ARRAY, 정형 OBJECT, MAP 값을 전달할 수 있어요. 반정형 데이터 타입의 경우와 마찬가지로 PATH 인자를 사용해 펼쳐지는 값을 지정할 수 있어요.

  • 펼쳐지는 값이 정형 ARRAY 값이고 RECURSIVE 인자가 FALSE이면, value 열은 ARRAY 값과 같은 타입의 값을 담아요.

예를 들어:

SELECT value, SYSTEM$TYPEOF(value)
  FROM TABLE(FLATTEN(INPUT => [1.08, 2.13, 3.14]::ARRAY(DOUBLE)));
+-------+----------------------+
| VALUE | SYSTEM$TYPEOF(VALUE) |
|-------+----------------------|
|  1.08 | FLOAT[DOUBLE]        |
|  2.13 | FLOAT[DOUBLE]        |
|  3.14 | FLOAT[DOUBLE]        |
+-------+----------------------+
  • 펼쳐지는 값이 MAP 값이고 RECURSIVE 인자가 FALSE이면, key 열은 MAP 키와 같은 타입의 키를 담고, value 열은 MAP 값과 같은 타입의 값을 담아요.

예를 들어:

SELECT key, SYSTEM$TYPEOF(key), value, SYSTEM$TYPEOF(value)
  FROM TABLE(FLATTEN(INPUT => {'my_key': 'my_value'}::MAP(VARCHAR, VARCHAR)));
+--------+--------------------+----------+----------------------+
| KEY    | SYSTEM$TYPEOF(KEY) | VALUE    | SYSTEM$TYPEOF(VALUE) |
|--------+--------------------+----------+----------------------|
| my_key | VARCHAR[LOB]       | my_value | VARCHAR[LOB]         |
+--------+--------------------+----------+----------------------+
  • 그렇지 않으면 keyvalue 열은 VARIANT 타입이에요.

MAP 값의 경우 반환되는 키와 값의 순서는 결정되지 않아요(indeterminate).

PARSE_JSON 함수 사용하기 (Using the PARSE_JSON function)

PARSE_JSON 함수는 정형 타입을 반환하지 않아요.

집합 연산자와 CASE 표현식과 함께 정형 타입 사용하기 (Using structured types with set operators and CASE expressions)

정형 ARRAY, 정형 OBJECT, MAP 값을 다음에서 사용할 수 있어요.

집합 연산자의 경우 서로 다른 표현식에 서로 다른 타입이 사용되면(예: 하나는 ARRAY(NUMBER)이고 다른 하나는 ARRAY(DOUBLE)), 한 타입이 다른 타입으로 강제 변환돼요.

다른 반정형 함수와 작업하기 (Working with other semi-structured functions)

다음 함수는 입력 인자로 정형 ARRAY, 정형 OBJECT, MAP 값을 받지 않아요.

정형 타입 값을 입력으로 전달하면 오류가 발생해요.

드라이버를 사용하는 애플리케이션에서 정형 타입 접근하기 (Accessing structured types in applications using drivers)

드라이버(예: ODBC 또는 JDBC 드라이버, Python용 Snowflake Connector 등)를 사용하는 애플리케이션에서 정형 타입 값은 반정형 타입 값으로 반환돼요. 예를 들어:

  • 정형 ARRAY 열의 값은 클라이언트 애플리케이션에 반정형 ARRAY 값으로 반환돼요.
  • 정형 OBJECT 또는 MAP 열의 값은 클라이언트 애플리케이션에 반정형 OBJECT 값으로 반환돼요.

참고: JDBC 드라이버를 사용하는 클라이언트 애플리케이션의 경우, 검색하려는 쿼리 결과에 NULL 값이 있는 정형 ARRAY 값이 포함되어 있으면 ResultSet.getArray() 메서드는 오류를 반환해요. 대신 문자열 표현을 검색하려면 ResultSet.getString() 메서드를 사용해요.

String result = resultSet.getString(1);

사용자 정의 함수(UDF)와 저장 프로시저와 함께 정형 타입 사용하기 (Using structured types with user-defined functions (UDFs) and stored procedures)

SQL, Snowflake Scripting, Java, Python, Scala로 사용자 정의 함수(UDF), 사용자 정의 테이블 함수(UDTF), 저장 프로시저를 만들 때 인자와 반환 값에 정형 타입을 사용할 수 있어요. 예를 들어:

CREATE OR REPLACE FUNCTION my_udf(
    location OBJECT(city VARCHAR, zipcode NUMBER, val ARRAY(BOOLEAN)))
  RETURNS VARCHAR
  AS
  $$
    ...
  $$;
CREATE OR REPLACE FUNCTION my_udtf(check BOOLEAN)
  RETURNS TABLE(col1 ARRAY(VARCHAR))
  AS
  $$
  ...
  $$;
CREATE OR REPLACE PROCEDURE my_procedure(values ARRAY(INTEGER))
  RETURNS ARRAY(INTEGER)
  LANGUAGE SQL
  AS
  $$
    ...
  $$;
CREATE OR REPLACE FUNCTION my_function(values ARRAY(INTEGER))
  RETURNS ARRAY(INTEGER)
  LANGUAGE PYTHON
  RUNTIME_VERSION=3.10
  AS
  $$
    ...
  $$;

참고: 정형 타입은 JavaScript의 UDF, UDTF, 저장 프로시저에서 아직 지원되지 않아요.

정형 타입에 대한 정보 보기 (Viewing information about structured types)

다음 섹션은 정형 타입에 대한 정보를 보는 데 사용할 수 있는 뷰와 명령을 설명해요.

  • SHOW COLUMNS 명령을 사용해 정형 타입 정보 보기
  • DESCRIBE와 다른 SHOW 명령을 사용해 정형 타입 정보 보기
  • 데이터베이스에서 사용된 정형 타입에 대한 정보 보기

SHOW COLUMNS 명령을 사용해 정형 타입 정보 보기 (Using the SHOW COLUMNS command to view structured type information)

SHOW COLUMNS 명령의 출력에서 data_type 열은 요소, 키, 값의 타입 정보를 포함해요.

DESCRIBE와 다른 SHOW 명령을 사용해 정형 타입 정보 보기 (Using the DESCRIBE and other SHOW commands to view structured type information)

다음 명령의 출력은 정형 타입에 대한 정보를 포함해요.

예를 들어 DESCRIBE RESULT 출력에서 MAP(VARCHAR, VARCHAR) 열의 행은 type 열에 다음 값을 포함해요.

map(VARCHAR, VARCHAR)

ARRAY(NUMBER) 열의 행은 type 열에 다음 값을 포함해요.

ARRAY(NUMBER(38,0))

데이터베이스에서 사용된 정형 타입에 대한 정보 보기 (Viewing information about the structured types used in a database)

정형 타입 열의 경우, INFORMATION_SCHEMA COLUMNS 뷰는 열의 기본 데이터 타입(ARRAY, OBJECT, MAP)에 대한 정보만 제공해요.

예를 들어 data_type 열은 단지 ARRAY, OBJECT, MAP만 포함해요. 열은 요소, 키, 값의 타입을 포함하지 않아요.

요소, 키, 값의 타입에 대한 정보를 보려면 다음 뷰를 사용해요.

  • 정형 ARRAY 타입의 요소 타입 정보는 INFORMATION_SCHEMA의 ELEMENT_TYPES 뷰 또는 ACCOUNT_USAGE의 ELEMENT_TYPES 뷰를 쿼리해요.
  • 정형 OBJECT와 MAP 타입의 키와 값 타입 정보는 INFORMATION_SCHEMA의 FIELDS 뷰 또는 ACCOUNT_USAGE의 FIELDS 뷰를 쿼리해요.

더 알아보기 (Learn more)