Azure Data Factory v2 を使用してクラウド データ ウェアハウスに取り組んでいます。私のデータ ソースの多くは、オンプレミスの Oracle 12g データベースです。テーブル 1-1 の抽出は問題ではありません。ただし、ときどき、コピー アクティビティでその場でパラメーター化された計算によって生成されたデータを抽出する必要があります。
PL/SQL ストアド プロシージャを ADF のソースとして使用できないため、代わりにソース データベースでテーブル値関数を使用し、コピー アクティビティでクエリを実行します。
ほとんどの場合、これで問題なく動作します。ただし、テーブル値関数が 10 進数型の列を返すと、ADF が誤った値を返すことがあります。つまり、ソース データベースで TVF を実行し、ADF を介してプレビュー/コピーすると、異なる結果が得られます。
10 進数の絶対値または符号が重要な場合は、いくつかの実験を行いましたが、10 進数が正しく返されるパターンとそうでないパターンを見つけることができません。
誤ってマッピングされた数値の例をいくつか示します。
Oracle データベースの値 | ADF の値 |
---|---|
-658388.5681 | 188344991.6319 |
-205668.1648 | 58835420.6352 |
10255676.84 | 188213627.97348 |
- 同様の問題を経験した人はいますか?
- これが ADF のバグ (そもそも PL/SQL にうまく統合されていない) かどうか知っていますか?
最初の仮説
最初は、この問題は NLS やキャスティングなどに関連していると思いました。この仮説をテストするには、Oracle db 側でテーブルを作成し、そこで TVF からの出力を永続化し、ADF でテーブルから抽出しました。このメソッドを使用すると、ADF で小数が正しく返されました。したがって、仮説は成立しません。
2番目の仮説
ユーザーアクセスに関係している可能性があります。ただし、ADF で使用されるリンクされたサービスは、データベースへのログインに使用されるものと同じ db 資格情報を使用して、そこで TVF を実行します。
観察
多くの集計関数が tvf のロジックに関与している場合、エラーがより頻繁に発生するようです。
最小限の再現可能な例
Oracle データベース:
CREATE OR REPLACE TYPE test_col AS OBJECT
(
dec_col NUMBER(20,5)
)
/
CREATE OR REPLACE TYPE test_tbl AS TABLE OF test_col;
create or replace function test_fct(param date) return test_tbl
AS
ret_tbl test_tbl;
begin
select
test_col(
<"some complex logic which return a decimal">
)
bulk collect into ret_tbl
from <"some complex joins and group by's">;
return ret_tbl;
end test_fct;
select dec_col from table(test_fct(sysdate));
ADF: データセット:
{
"name": "test_dataset",
"properties": {
"linkedServiceName": {
"referenceName": "some_name",
"type": "LinkedServiceReference"
},
"folder": {
"name": "some_name"
},
"annotations": [],
"type": "OracleTable",
"structure": [
{
"name": "dec_col",
"type": "Decimal"
}
]
}
}
パイプライン:
{
"name": "pipeline1",
"properties": {
"activities": [
{
"name": "Copy data1",
"type": "Copy",
"dependsOn": [],
"policy": {
"timeout": "7.00:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false,
"secureInput": false
},
"userProperties": [],
"typeProperties": {
"source": {
"type": "OracleSource",
"oracleReaderQuery": "select * from table(test_fct(sysdate))",
"partitionOption": "None",
"queryTimeout": "02:00:00"
},
"enableStaging": false
},
"inputs": [
{
"referenceName": "test_dataset",
"type": "DatasetReference"
}
]
}
],
"annotations": []
}
}