LoginSignup
4
0

More than 1 year has passed since last update.

Db2:レコードが登録されたらスマートフォンに通知したい

Posted at

背景と状況

データベースにデータが登録されたらすぐに知りたいと思ったことはありませんか。ユースケースとしては電子カルテに検査結果が登録されたらスマートフォンに通知するなどがあります。

やりたいこと

レコードが登録されたらスマートフォンに通知したい。具体的にはレコードのインサート、アップデートが発生したら、通知プログラムを実行したい。今回はLINEを使いますがSlackなどほかのアプリにも応用可能です。

やり方

Db2の ユーザー定義関数(User Defined Functions 以下UDF) を使って、LINEにメッセージを送ります。LINEへのメッセージはLINE Notifyを使います。また、インサート、アップデートなどの イベントを検知するのにDb2のトリガー を使います。

  1. LINE Notifyのトークン取得
  2. LINE Notifyの稼働確認
  3. JavaでLINE Notifyを実装
  4. UDFの作成
  5. トリガーの定義
  6. レコードのインサートによる稼働確認

環境

  • Windows 11
  • IBM Db2 V11.5 Windows

LINE Notifyのトークン取得

こちらの記事を参考にLINE Notifyのサイトからトークンを取得します。

LINE Notifyの稼働確認

こちらの記事を参考に取得したトークンでLINEにメッセージが送付できるかを確認してください。

JavaでLINE Notifyを実装

こちらのGitHubにあるJavaのソースを参考にLineNotify.javaを用意します。

LineNotify.java
import java.io.*;
import java.net.*;
import java.util.regex.Pattern;

public class LineNotify {
	public static String callEvent(String token, String message) {
		String result = "false";
   		try {
			String strUrl = "https://notify-api.line.me/api/notify";  // 通知用エンドポイント
			message = URLEncoder.encode(message, "UTF-8");
			URL url = new URL( strUrl );
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.addRequestProperty("Authorization",  "Bearer " + token);
			connection.setRequestMethod( "POST" );
			connection.addRequestProperty( "Content-Type", "application/x-www-form-urlencoded" );
			connection.setDoOutput( true );
			String parameterString = new String("message=" + message);
			PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
			printWriter.print(parameterString);
			printWriter.close();
			connection.connect();
            
			int statusCode = connection.getResponseCode();
		        if ( statusCode == 200 ) {
		        	result = "true";
		        } else {
		        	throw new Exception( "Error:(StatusCode)" + statusCode + ", " + connection.getResponseMessage() );
		        }
		        connection.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	private String replaceProcess(String txt){
    		txt = replaceAllRegex(txt, "\\\\", "¥");		// \
		return txt;
	}
	private String replaceAllRegex(String value, String regex, String replacement) {
		if ( value == null || value.length() == 0 || regex == null || regex.length() == 0 || replacement == null )
			return "";
		return Pattern.compile(regex).matcher(value).replaceAll(replacement);
	}
}

稼働確認用にmain.javaも用意します。

Main.java
public class Main {

    public static void main(String[] args) {

        String result ;

        LineNotify objetct1 = new LineNotify();
        result = objetct1.callEvent(args[0],args[1]);

        System.out.print(result);
    }
}

Db2にインストールされているJDKを使ってコンパイルします。
D:\SQLLIB\java\jdk\bin\javac Main.java
image.png

作成したクラスの稼働確認をします。
D:\SQLLIB\java\jdk\bin\java Main 取得したトークン "JavaからLINE Notify"

jarファイルを作成します。
D:\SQLLIB\java\jdk\bin\jar -cvf LineNotify.jar LineNotify.class
image.png

jarファイルを格納するフォルダーにコピー、Db2にインストールします。
copy LineNotify.jar D:\myapp_jar
db2 connect to データベース名 user ユーザー名
db2 "CALL SQLJ.INSTALL_JAR('file:D:/myapp_jar/LineNotify.jar', 'LINENOTIFY')"
image.png

jarは以下のフォルダーに格納されます。
D:\DB2PROFS\IBM\DB2\DB2COPY1\function\jar\DB2ADMIN
image.png

格納したjarを更新、削除したい場合は以下のコマンドを使用します。

置換
db2 "CALL SQLJ.REPLACE_JAR('file:D:/myapp_jar/LineNotify.jar', 'LINENOTIFY')"
db2 "CALL SQLJ.REFRESH_CLASSES()"
除去
db2 "CALL SQLJ.REMOVE_JAR('LINENOTIFY')"

UDFの作成

UDF定義用のDDLを準備、以下のコマンドでUDFを定義します。
db2 -tvf LineNotifyUDF.ddl

LineNotifyUDF.ddl
DROP   PROCEDURE LINENOTIFY ;
DROP   FUNCTION LINENOTIFY ;

CREATE FUNCTION LINENOTIFY (IN TOKEN CHAR(100) , IN MESSAGE CHAR(200)) 
RETURNS CHAR(200)
EXTERNAL NAME 'LineNotify.callEvent' 
LANGUAGE JAVA 
PARAMETER STYLE JAVA 
SPECIFIC LINENOTIFY 
CALLED ON NULL INPUT
NO SQL
;                                                                                                                                                                                         

プロシージャーとファンクションが事前定義されていない場合はエラーになりますが問題ありません。
image.png

UDFを稼働確認します。
db2 "CALL SQLJ.REFRESH_CLASSES()"
db2 select LINENOTIFY('取得したトークン','DB2からLINE Notify') FROM SYSIBM.SYSDUMMY1
image.png

うまくいくと以下のようにLINEに通知が行きます。
image.png

UDFを確認、除去したい場合は以下のコマンドを使用します。

確認
db2 SELECT ROUTINESCHEMA, ROUTINENAME, FENCED, LANGUAGE FROM SYSCAT.ROUTINES WHERE ROUTINESCHEMA='DB2ADMIN'
除去
db2 drop FUNCTION LINENOTIFY

トリガーの定義

トリガーのレコードがインサートされたらUDFが動くトリガーを用意、以下のコマンドで定義します。テーブル名は各自の環境に合わせて変更してください。
db2 -tvf TriggerLineNotifyUDF.ddl

TriggerLineNotifyUDF.ddl
CREATE TRIGGER LINENOTIFY
  AFTER INSERT ON TKNTIDX
  REFERENCING NEW AS N_ROW
  FOR EACH ROW MODE DB2SQL
  
    select LINENOTIFY('取得したトークン', 
                       rtrim(KJ_KAN_NM) || 'さんの検査結果が出ました。')  
      from tjptkhn where pt_id = N_ROW.PT_ID
;

レコードのインサートによる稼働確認

レコードをインサートするとLINEにメッセージが送られます。

insert.sql
insert into tkntidx select 
'000001', 
'00000001', 
current date, 
current time, 
'999999', 
current date ,
'',
'',
'',
'',
'',
'',
'',
current date, 
current time, 
'',
'',
'',
'',
'',
'',
current time, 
'',
''
from sysibm.sysdummy1 ;

正しく設定ができると、以下のようなメッセージがLINEに届きます。
image.png

Javaでアプリに通知するロジックを記述すれば、UDFに定義できます。UDFに定義後、select文で簡単にプログラムが起動します。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0