CDATA SAS.dsを使ってみる(その2:属性編)
CDATA SAS.dsを使ってみる(その1:データセットアクセス編)
に続き、CDATA SAS dataset Firedac componentの検証記事です
(いずれも検証時点で入手可能なβ版 21.0.7829 を使用しています)
今回はSASデータセットのディスクリプタ部、属性について調べました。
属性は完璧には取得できない
検証に使用したデータセットです
data temp.fmt;
length char $10;
format
time time8.
yymmdd yymmdd10.
e8601dt e8601dt19.
date date9.
weekdate weekdate21.
nengo nengo9.
jnengo jnengo16.
jdateymd jdateymd14.
datetime datetime16.
yen yen8.
dollar dollar12.2
comma comma7.
z z7.
hex hex6.
best12 best12.
best32 best32.
;
array n{*} _numeric_;
do i=1 to dim(n);
n{i}=10000;
end;
char='SAMPLE';
best12=1234567890.1234567;
best32=1234567890.1234567;
drop i;
run;
さて、属性はTFDMetaInfoQueryを使い、以下のように取得します
var cnt:integer; begin FDMetaInfoQuery1.Close; FDMetaInfoQuery1.Connection := FDConnection1; FDMetaInfoQuery1.MetaInfoKind := mkTableFields; FDMetaInfoQuery1.ObjectName := Combobox1.Items[Combobox1.ItemIndex]; FDMetaInfoQuery1.Open; cnt:=0; StringGrid1.RowCount:=FDMetaInfoQuery1.RecordCount; StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); StringGrid1.AddObject(TStringColumn.Create(StringGrid1)); StringGrid1.Columns[0].Header := 'Name'; StringGrid1.Columns[1].Header := 'Length'; StringGrid1.Columns[2].Header := 'Precision'; StringGrid1.Columns[3].Header := 'DataType.'; StringGrid1.Columns[4].Header := 'TypeName'; while(not(FDMetaInfoQuery1.Eof))do begin StringGrid1.Cells[0,cnt]:= FDMetaInfoQuery1.FieldByName('COLUMN_NAME').AsString; StringGrid1.Cells[1,cnt]:= FDMetaInfoQuery1.FieldByName('COLUMN_LENGTH').AsString; StringGrid1.Cells[2,cnt]:= FDMetaInfoQuery1.FieldByName('COLUMN_PRECISION').AsString; StringGrid1.Cells[3,cnt]:= FDMetaInfoQuery1.FieldByName('COLUMN_DATATYPE').AsString; StringGrid1.Cells[4,cnt]:= FDMetaInfoQuery1.FieldByName('COLUMN_TYPENAME').AsString; inc(cnt); FDMetaInfoQuery1.Next; end; FDMetaInfoQuery1.Close;
さて、結果は以下の通りです。
実データはどうなってるでしょう。
char / SAMPLE time / 2:46:40 yymmdd / 1987/05/19 e8601dt / 1960/01/01 2:46:40 date / 1987/05/19 weekdate / 1987/05/19 nengo / 10000 jnengo / 10000 jdateymd / 10000 datetime / 1960/01/01 2:46:40 yen / 10000 dollar / 10000 comma / 10000 z / 10000 hex / 10000 best12 / 1234567890.12346 best32 / 1234567890.12346
SASと同じ結果で認識できているのはNumeric型では
- time8.
- yymmdd10.
だけでした。
他の結果については
- e8601dtは日付と時刻の間の「T」がない
- date、weekdate、datetimeは日付値、日時値として認識されているが、正しいフォーマットではない
- 日時以外の数値フォーマットについては軒並み生データのまま。
- 16桁を超える数値については、最終桁が丸められている
また、属性については
- Characterの場合は、lengthはそのまま取得できる。
- フォーマットが適用された日付の場合は型が「datetime / date / time」となり、lengthもprecisionも0となる。値自体はロケールに依存しそうな気配(未確認)
- Numericの場合は、lengthは0になり、precision(精度)が15(桁)のdouble型となる。
SQLにはSASのような「ラベル」「フォーマット」という概念がありませんので、そもそもラベルもフォーマットもその属性を取得することはできませんでした。
(なので、データ構造が公開されているXPTではバイナリから取得していました)
また、SASを起動しているわけではないのでDictionaryテーブルから情報を取得することもできません。
したがって、メタデータが必要であれば当該データセット以外に情報を保持しておく必要がありそうです。
なお、インデックスについては
FDMetaInfoQuery1.MetaInfoKind := mkIndexes;
で取得できるはずなのですが、SASのインデックスは取得できませんでした。