メイン コンテンツをスキップする

代替のデータ型

Data Shaping Query Languageでは、Avroスキーマを使い、同じエレメントに対して複数のデータ型を扱うことができます。 Avroスキーマの詳細は、Oracleのドキュメンテーションをご覧ください。
次のサンプルJSON入力では、order_amountというエレメントは次のいずれかとなります:
  • 整数
  • 10進数
  • 文字列
  • 2つの小数値(items_totaltax_amount)が含まれているレコード
{
    "orders": [
        {
            "order_id": "abc-12345",
            "order_amount": 250
        },
        {
            "order_id": "def-67890",
            "order_amount": "299.99"
        },
        {
            "order_id": "ghi-54321",
            "order_amount": 435.95
        },
        {
            "order_id": "jkl-09876",
            "order_amount": {
                "items_total": 395.99,
                "tax_amount": 11.89
            }
        }
    ]
}
この入力は次のAvroスキーマで記述されます:
{
    "type": "record",
    "name": "root",
    "fields": [
        {
            "name": "orders",
            "type": {
                "type": "array",
                "items": {
                    "type": "record",
                    "name": "order",
                    "fields": [
                        {
                            "name": "order_id",
                            "type": "string"
                        },
                        {
                            "name": "order_amount",
                            "type": [
                                "int",
                                {
                                    "type": "bytes",
                                    "logicalType": "decimal"
                                },
                                "string",
                                {
                                    "type": "record",
                                    "name": "amount",
                                    "fields": [
                                        {
                                            "name": "items_total",
                                            "type": {
                                                "type": "bytes",
                                                "logicalType": "decimal"
                                            }
                                        },
                                        {
                                            "name": "tax_amount",
                                            "type": {
                                                "type": "bytes",
                                                "logicalType": "decimal"
                                            }
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    ]
}

Data Shaping Query Languageでは、identifier.@indexという構文を使い、エレメントの識別子に型のインデックスを付加することで、それぞれの可能な型を参照できます。この例では、intorder_amountエレメントで可能な型のリストの最初の値なので、order_amount.@0で参照できます。

この構文は階層識別子でも使用できます。たとえば、order_amount.@3.tax_amountを使ってレコード内のtax_amountエレメントを参照できます。

resolveChoiceファンクションを使用すれば、それぞれの反復やエレメントに使用される型を識別できます。このファンクションの詳細は、特別ファンクションをご覧ください。

この例では、次のクエリーを使い、orders配列の各項目でorder_amountエレメントに使用されているデータ型を取得できます:
FROM orders
SELECT {
    order_id,
    amount = resolveChoice(order_amount)
}
このクエリーは次の結果を返します:
[
    {
        "order_id": "abc-12345",
        "amount_type": 0
    },
    {
        "order_id": "def-67890",
        "amount_type": 2
    },
    {
        "order_id": "ghi-54321",
        "amount_type": 1
    },
    {
        "order_id": "jkl-09876",
        "amount_type": 3
    }
]
次に、データを調整し、order_amountエレメントで単一のデータ型を返すクエリーを書くことができます。たとえば次のクエリーを使用できます:
  • スイッチ式とresolveChoiceファンクションを使って、それぞれの代替インデックスにデータ型を割り当てます。
  • toDecimalファンクションを使って、文字列と整数値を小数に変換します。
  • items_totaltax_amountを加え、各レコードの合計金額を計算します。
FROM orders
LET $amount_type = 
    SWITCH (resolveChoice(order_amount)) { 
		CASE 0: 'INT' 
		CASE 1: 'DECIMAL' 
		CASE 2: 'STRING' 
		CASE 3: 'RECORD' 
	}
SELECT {
    order_id,
    amount = 
        IF ($amount_type = "STRING" OR $amount_type = "INT") 
            toDecimal(order_amount)
        ELSEIF ($amount_type = "RECORD")
            order_amount.@3.items_total + order_amount.@3.tax_amount
        ELSE order_amount
}
このクエリーでは、order_amountの反復はそれぞれ入力タイプに関係なく10進値に変換されます。以下の結果が返されます:
[
    {
        "order_id": "abc-12345",
        "amount": 250
    },
    {
        "order_id": "def-67890",
        "amount": 299.99
    },
    {
        "order_id": "ghi-54321",
        "amount": 435.95
    },
    {
        "order_id": "jkl-09876",
        "amount": 407.88
    }
]

このページは役に立ちましたか?

このページまたはコンテンツにタイポ、ステップの省略、技術的エラーなどの問題が見つかった場合はお知らせください。