Delphi / FireDAC　Oracle Database Express Editionで、画像とPDFの保存と取り出しのテストをしてみました。

# はじめに
## Delphi Advent Calendar 2022 12/05と12/07と12/08と12/11と12/13の記事の[Oracle Database Express Edition](https://www.oracle.com/jp/database/technologies/appdev/xe.html) 版です。
## 今回は、電子帳簿の管理などで役立つかもの、BLOBに、PDFを保存して、呼び出したPDFをブラウザで、参照する処理を追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/b144e46f-a367-31e7-bf0a-92e9bfbf6ad7.png)
### 1.　[Oracle Database Express Edition](https://www.oracle.com/jp/database/technologies/appdev/xe.html) は、Windows10にインストール(バージョンは21c)、接続の検証は、[A5SQL Mk2](https://a5m2.mmatsubara.com/)　で行いました。
[A5SQL Mk2](https://a5m2.mmatsubara.com/)　は、たしか Delphi製だったかと思うのですが、直接接続なるものが設定でき、[Oracle Instant Client](https://www.oracle.com/jp/database/technologies/instant-client.html)は不要で接続できますが、今回は、FireDACでの接続なので、oci.dllなどのdllが、必要なので、Oracle Instant Client　を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/48339b9a-ff0f-7e5a-0ad9-c13da320242f.png)
### 2.　Oracle Database Express Edition データベースは　XE を使用(変更不可だったと思います?)
![a5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/953f02a7-a38d-fd95-1df1-a23a35488912.png)
### 3.　Oracle Database Express Edition では、データ型は BLOB です
### 4.　Delphiで、uses ShellAPI, JPEG, GIFImg, PNGImage ; //使用する画像とPDFをブラウザで参照するのでShellAPI も宣言

Delphi 10.2でテストしています。
赤枠の部分が、12/05と12/07と12/08と12/11と12/13　にはなく、今回追加した処理で、今回は追加部の説明を記事にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/7f4311f4-0f1c-5020-0836-db38abc0e141.png)
***
#### 以下サンプルコード
### PDFデータの追加のサンプルコード
```Delphi:FD_Oracle_Express_21c_b_Unit.pas
procedure TForm1.SpeedButton10Click(Sender: TObject);
var
  SQLstmt:String;
begin
  with FDConnection1 do
  try
    SQLstmt :=' INSERT INTO '
             +' test_tbl ( ts_no  , tsblob ) '
             +'	VALUES ('
             +' :ts_no , :tsblob '
             + ')';
    FDQuery1.SQL.Clear;
    FDQuery1.SQL.Text:= sqlstmt;
    FDQuery1.ParamByName('ts_no').AsInteger:=StrToInt( Edit_TS_NO_2.Text );
    FDQuery1.ParamByName('tsblob').LoadFromFile( Edit_Files_PDF.Text ,ftBlob);
    FDQuery1.ExecSQL();
    ShowMessage('登録しました');
  finally
    FDQuery1.Close;
  end;
end;
```


### PDFをDBから読込みして、tmp_1.pdfに保存のサンプルコード
```Delphi:FD_Oracle_Express_21c_b_Unit.pas
procedure TForm1.SpeedButton11Click(Sender: TObject);
var
  SQLstmt:String;
begin
  with FDConnection1 do
  try
    SQLstmt := 'SELECT * FROM test_tbl '
            +  'WHERE ts_no = :ts_no';
    FDQuery1.SQL.Clear;
    FDQuery1.SQL.Text:= sqlstmt;
    FDQuery1.ParamByName('ts_no').AsInteger:=StrToInt(Edit_TS_NO_2.Text);
    FDQuery1.Open();
    if not FDQuery1.Eof then
    begin
      Edit_TS_NO_2.Text  :=IntToStr(FDQuery1.FieldByName('ts_no').AsInteger);
      TBLOBField(FDQuery1.FieldByName('tsblob') ).SaveToFile(GetCurrentDir+'\'+'tmp_1.pdf' );
    end;
  finally
    FDQuery1.Close;
  end;
end;
```
### 保存したPDFのtmp_1.pdfをクロームで参照するサンプルコード
```Delphi:FD_Oracle_Express_21c_b_Unit.pas
procedure TForm1.SpeedButton12Click(Sender: TObject);
var
  LExeName : String;
  LUrl     : String;
begin
  LExeName := 'chrome.exe';
  LUrl     := 'file:/'+GetCurrentDir+'\'+'tmp_1.pdf';
  ShellExecute(Handle, 'open', PChar(LExeName), PChar(LUrl), nil, SW_SHOW);
end;
```

[Oracle Instant Client](https://www.oracle.com/jp/database/technologies/instant-client.html)
から、下記のdllを実行ファイルに配置して、使用しました、すべて必要なのかどうかは検証していません。
embarcaderoさんのドキュメント[Oracle サーバーへの接続（FireDAC](https://docwiki.embarcadero.com/RADStudio/Sydney/ja/Oracle_%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%B8%E3%81%AE%E6%8E%A5%E7%B6%9A%EF%BC%88FireDAC%EF%BC%89)には、4つを配置とあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/bc91f932-16a9-089b-5ab4-84f16475ea13.png)

tnsnames.oraは、Oracle Database Express Edition をインストールした、Windows10からコピーして、今回は、マシン名をIPアドレスに変更してしようしました。
(Oracleをインストールしたマシンの　C:\app\w10o\product\21c\homes\OraDB21Home1\network\admin　から)
![tns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/8344b053-0d0f-26ec-3e97-0e4705c82950.png)

```Oracle Database Express Edition : tnsnames.ora
# tnsnames.ora Network Configuration File: C:\app\w10o\product\18.0.0\dbhomeXE\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.

XE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.24.51)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

LISTENER_XE =
  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.24.51)(PORT = 1521))


ORACLR_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
    (CONNECT_DATA =
      (SID = CLRExtProc)
      (PRESENTATION = RO)
    )
  )
```


#### わかっている方には、当たり前なのかもしれませんが、FireDACで、Oracleに接続する場合、tnsnames.oraが、クライアント側に必要となります。普段PostgreSQLやMySQLを使われていて、はじめて、Oracleに接続するときの、ハマりどころかもしれません。

#### エラーで、[FireDAC][Phys][Ora]-314. ベンダ ライブラリ [D:\2022_Oracle_Express_21c_B\Win32\Debug\oci.dll] を読み込めません。指定されたモジュールが見つかりません。が表示される場合
![ora_err.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88517/962ac73a-03e8-8ebe-4333-aaa823fa15d7.png)
Microsoft Visual C++のランタイムがインストールされていない場合にでるようなので、[Microsoft Visual C++再頒布可能な最新のサポートされているダウンロード](https://learn.microsoft.com/ja-jp/cpp/windows/latest-supported-vc-redist?view=msvc-170)
からダウンロードとインストールが必要です。


#### このDelphiのサンプルソースのダウロードは、ここからできます
http://a23.sblo.jp/article/190004577.html