Oracle接続を図解する＜静的なサービス登録＞

##Oracleに接続するための「サービス登録」
クライアントからOracleデータベースに接続するにあたっては、
リスナープロセスがいったん接続要求を受け付けて、クライアントが要求する「サービス」の名前を見て、最終目的地であるインスタンス(データベース)に転送してくれます。
郵便に例えるなら「サービス名」は表札、名札のようなもの、「インスタンス(データベース)」は本当の宛先、おうちです。
そして「リスナー」は郵便配達人。

リスナーがクライアントの要求通りデータベースにリクエストを転送できるのは、
「どのサービスをどのOracleインスタンスが提供しているか」の情報を知っているからです。
言い換えると、どのおうちに、何という名前の名札がかかっているかを知っている、ということ。

これらのサービス(≒名札)の情報は、listener.oraファイルにあらかじめ書いておくか、動的にリスナーに登録する仕組みを利用することができます。
前者の仕組みは、Oracleマニュアルでは「リスナーへの静的サービスの追加」「静的な登録」などと呼ばれます。
（後者の仕組みについては[「Oracle接続＜動的サービス登録」](https://qiita.com/mi-kana/items/862305b7f5fdee8d080d)で別途メモを残していますのでここでは触れません）

![listener_abstract.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/d01847ed-9caa-55a2-6524-e925977cd270.png)


##サービスとは

 * クライアントがインスタンスに接続するための名前
 * Oracleインスタンスが提供するサービスの名前(≒データベース名)


## 静的な登録

* ユーザーが手動で listener.ora ファイルにサービスの情報を記述する方法
* listener.oraファイルを手動編集する、Oracle Net Manager で登録するなどの手段がある

### リスナーへの静的サービスの追加のイメージ
![Image_sid_service_add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/3c284825-7968-c391-5da7-98450466d5ec.png)




* 初期化パラメータ SERVICE_NAMES には、サービス名を複数定義することができます
* 「サービス名」は、あるOracleインスタンス(データベース) に対して、名札をつけるイメージです。名札は１つだけでも、複数あっても構いません
* 「サービス名」が名札なら、「リスナー」は郵便配達人に例えることができます
* ユーザが、データベースにかけられている1つ以上の「名札（サービス名）」の情報を listener.oraファイルに記述し、リスナープロセスを再起動することで「郵便配達人（リスナー）」に伝えることによって、クライアントから接続要求が届いたときに、「郵便配達人（リスナー）」は接続要求にかかれた「名札（サービス）」を読み取り、正しいデータベース宛に転送することができるようになります
* クライアントは、複数あるサービス名のうち1つを指定すれば、データベースに接続することができます

###Oracle Net Manager での静的なサービス登録例

* 登録するサービス名「PANDADB」
* 対象のリスナーを選択して、ドロップダウンリストから「データベース・サービス」を選択すると追加・削除・編集できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/3ff6ceb0-5ec9-a8e8-6d72-678c379af9cc.png)


### 静的にサービス名が登録された listener.ora
![sid_service_add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/37016747-ff61-ed23-37f2-c8a62b472be1.png)


### 静的に登録されたサービスを認識させるため、リスナー再起動
Windows環境のため、サービス画面から再起動
![windows_service(listener)_restart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/db483853-aa63-af3d-f9e1-6cc03c504e78.png)

### lsnrctlコマンドによる確認
 * lsnrctl services コマンドを実行すると、リスナーが認識している「サービス名」がわかります。
 * 出力されるサービス名のうち、状態が「UNKNOWN」とされるのが、静的に登録されたサービスです。

```
C:\Users\KANA>lsnrctl services

LSNRCTL for 64-bit Windows: Version 19.0.0.0.0 - Production on 05-8月 -2019 18:36:31

Copyright (c) 1991, 2019, Oracle.  All rights reserved.

(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=DESKTOP-5RC350R)(PORT=1521)))に接続中
サービスのサマリー...
サービス"CLRExtProc"には、1件のインスタンスがあります。
  インスタンス"CLRExtProc"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "DEDICATED" 確立:0 拒否:0
         LOCAL SERVER
サービス"PANDADB"には、1件のインスタンスがあります。
  インスタンス"ORCL"、状態UNKNOWNには、このサービスに対する1件のハンドラがあります...
    ハンドラ:
      "DEDICATED" 確立:0 拒否:0
         LOCAL SERVER
コマンドは正常に終了しました。

C:\Users\KANA>
```

### 静的に登録したサービス名で接続してみる（簡易接続）

ここまでの作業で、簡易接続では「PANDADB」というサービス名を指定して接続できるようになっています。
静的に登録したサービス名「PANDADB」を指定して、接続してみます。

```
SQL> connect user/password@localhost:1521/PANDADB
接続されました。
```


### tnsnames.ora に、静的に登録した”PANDADB”のエントリーを追加
つづいて、ローカル・ネーミング・メソッドで接続できるように、tnsnames.ora にネット・サービス名を追加します。

**Oracle Net Mangerにて登録：**
「サービス・ネーミング」を選択して「＋」を選択すると、サービス・ネーミングの追加ウィザードが起動

 * ネット・サービス名「PANDA_SVC」
 * プロトコル「TCP/IP」
 * ホスト名 / ポート番号「myhost:1521」
 * サービス名「PANDADB」　← 静的に登録したサービス名を指定
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/451a180a-9666-5006-ed16-79aa47cedac4.png)

**tnsnames.ora**
![sid_service_net_service_add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468682/16fd0435-08d9-ee7e-e5cb-5fce2c9ec09a.png)


### 静的に登録したサービス名で接続してみる（ローカル・ネーミング）
ローカル・ネーミング・メソッドで接続（ネット・サービス名「PANDA_SVC」を指定する

```
SQL> connect user/password@PANDA_SVC
接続されました。
```