【データモデル】On Pre-Process for a tableを使ってみる

今回は、Sharperlightであるテーブルにクエリをかける前にその対象テーブルのデータを更新したい場合の解決方法を投稿してみようと思います。
幾つか方法はあるとは思いますが、この記事ではSharperlightデータモデルを使用します。

簡単な例として日付フィールドをもつテーブルとその日付フィールドを更新するストアドプロシジャーを用います。
要するにそのテーブルがクエリされる前にそのストアドプロシジャーを動作させてデータを更新させましょうということです。

とりあえずMicrosoft SQL Managerを利用して、空のデータベースを作成します。
その中にテーブルとストアドプロシジャーを準備します。
```
CREATE TABLE [dbo].[Qiita_OnPreProcess_Refresh](
	[RefreshedDateTime] [datetime] NOT NULL
)

  
CREATE PROCEDURE Qiita_Refresh
AS
	IF NOT EXISTS (SELECT 1 FROM [dbo].[Qiita_OnPreProcess_Refresh])
	BEGIN
		INSERT INTO [dbo].[Qiita_OnPreProcess_Refresh] ([RefreshedDateTime]) VALUES(getdate());
	END
	ELSE
	BEGIN
		UPDATE [dbo].[Qiita_OnPreProcess_Refresh] SET [RefreshedDateTime] = getdate();
	END
GO
```
動作確認を行います。
```
EXEC Qiita_Refresh

SELECT [RefreshedDateTime]
  FROM [Miscellaneous].[dbo].[Qiita_OnPreProcess_Refresh]
```
結果はこうなればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f3466c60-cd9a-12d5-e7b3-7350109c1735.png)


# データモデルの準備 #
ではSharperlightがそのテーブルにアクセスできるようデータモデルを準備します。
既存のデータモデルを使用する場合は、この手順は必要ありません。
Sharperlightアプリケーションメニューからスタジオを選択します。
Newアイコンをクリックし、新しいデータモデルの作成を開始します。
New Productダイアログが表示されます。**Description**、**Unique Code**と**Target Platform**を以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/56cbb820-4303-05a1-9548-22692c1855b0.png)
`OK`ボタンで先に進みます。
データベースへの接続情報を要求されるので、このように設定し接続ボタンで接続が正しく行われるかチェックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/015f3c99-13fa-7268-d18c-2ccec97c27d1.png)
`OK`ボタンで先に進みます。
テーブル情報を読み込みますかという問い合わせが開くので、`Yes`で先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ccdc8d06-3ace-c3df-ca15-a5f8a158a5b7.png)
Import Objectsダイアログが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/396c20fe-81ef-1585-3393-a2fc66ea8f01.png)
`Get Tables`ボタンでテーブル情報を読み取り表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7e25891c-610a-041e-17a9-9cb8c1ec9c6c.png)
`OK`ボタンで先に進みます。テーブル情報がデータモデルに読み込まれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/19e1fd62-69ee-a253-bc9e-aa2436453ecb.png)
ダイアログ左下部の`テーブル`をクリックし、テーブルの一覧を左側の領域に表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2a2bbfdf-9c66-f370-04e0-349189945870.png)
左上部のテーブルツリービューで、今回のテーブルをダブルクリックで選択します。
中央の領域には選択されたテーブルのフィールド情報が、右側の領域には、テーブル/フィールドのプロパティ情報が表示されます。
これで完了、このデータモデルを保存します。データモデルの保存先を問われるので、デフォルトの場所、つまり` C:\ProgramData\SharperLight\MetaData\`に保存します。
Sharperlightアプリケーション用にデータベース接続情報を入力します。（先ほどのはデータモデル用でした）
`Yes`で先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/72acabd9-b954-97ad-345b-13bbecc82f8a.png)
クライアントのセットアップが表示されます。
接続情報を入力し、テスト接続を実行し、正常に動作したなら`OK`ボタンで先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a746d08c-0249-20c1-797f-50bfc97fa9f6.png)
Sharperlightスタジオも閉じます。
以上でSharperlightアプリケーションを用いて、そのデータベース及びテーブルにアクセス可能となりました。

Sharperlightクエリビルダをアプリケーションメニューから開き、動作確認してみます。
製品（データモデル）、テーブルを指定し、表示されたフィールドを出力領域に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/22d62120-9ca9-3f52-26d3-993a010af703.png)
`プレビュー`ボタンでクエリを実行。正常に動きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/842daeb4-4e1c-1f86-1156-d01a388b5b37.png)

次はいよいよ本題です。
このままでは、最初に書き込んだ日付と時間がただクエリされるだけです。
データモデルを少し編集して、クエリが実行される前にストアドプロシジャーを実行させ、日付と時間を更新させます。

# On Pre-processの設定 #
先ほどのデータモデルを開き、テーブル情報を表示させます。
右側のプロパティ欄でOn Pre-process属性を見つけます。
ここにデータモデル内で定義するプロセス名を記入すれば、このテーブルがクエリされる前(Pre-process)に、その指定したプロセスが実行されます。
そしてそのプロセスでは、先に作成しておいたストアドプロシジャーをコールすればいいわけです。
では早速作業に取り掛かります。
## Processの定義 ##
Sharperlightスタジオを起動して先ほど作成したデータモデルを開きます。
下部左側の**Processes**を選び、`Custom Events`の右クリックメニューから**New Process**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/11b6e83d-09fc-4a1e-10f3-635e537503a1.png)
初期値の**SP0001**が作成されます。コード初期値**SP0001**を**P1**に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d851bef2-6e04-9816-7451-89b3d5440e65.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/589aa6b1-d28f-8c7d-a391-4f223b8641f0.png)
中央の表示域ではまだSP0001が表示されているかもしれません。中央の表示域の右角の`X`ボタンで消して、再度選択しなおすと、新しいコードP1が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5a82eec0-5121-4d46-6449-6954da6b6432.png)
次に、P1の右クリックメニューから**New SQL Command**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9c8502a7-0bb6-4c77-21a8-39c37a7ddd8a.png)
コードを**ExecSP**と変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/453b18d1-72c0-ab24-415b-773c7a9791cf.png)
**ExecSP**を選択し、中央下部テキスト領域を表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8218474a-a374-6044-a203-da15f6e1e40e.png)
そのテキスト領域にストアドプロシジャーを実行するコマンドを記入します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9faa6f18-0722-04d5-4ccd-9503a93704fb.png)
## Processの指定 ##
今度は、テーブル定義に移動。On Pre-process属性を選択し、検索ボタンを表示させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/517800ef-5f98-636d-ccdb-57cd75088e5c.png)
検索ダイログを表示し、先ほど作成したプロセス**P1**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/1698993e-e857-83cd-849b-f26d0d2bc59c.png)
このよな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/eca8232b-a4bd-ef04-a57f-d16a614ce6ab.png)

以上で完成。データモデルを保存します。

# 動作確認 #
Sharperlightアプリケーションメニューからクエリビルダを起動します。
製品(データモデル)、テーブルを選択し、日付時間フィールドを出力アイテムに設定。`プレビュー`ボタンでクエリを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a07599f4-796c-17ab-a2ff-957abfaf0911.png)
実行結果が表示されます。最初は、ストアドプロシジャーが実行されたかどうかは不明ですね。
今の結果を記録して、更新ボタンで再度クエリを実行。
どうですか結果は？時間が変更されているはずです。
数回試してみてください。ストアドプロシジャーが動作していることが確認できるはずです。

# おわりに #
今回は、時間を更新するだけといった極簡単なサンプルで紹介しましたが、日々の業務の中で、レポートを更新する前に最新の情報で対象テーブルを更新したいといった事が多々発生すると思われます。そういった場合にこのようなオプションは便利かもしれませんね。