こんにちは。株式会社ABEJAの@Takayoshi_maです。InfoQを見ているとこのようなニュースが掲載されていました。 どうやらMySQLでストアドファンクション・ストアドプロシージャを作成する際に新しくJavaScriptを使うことができるようになるそうです。私は普段BigQueryを触っているのですが、その際UDFにJavaScriptを使うことも多く、そう言った面からもこの機能がMySQLに実装されることは結構便利になるのでは?と思っているところです。
そこで、実は今回のブログではこの新しい機能を使ってみた系の話題を書こうかなと思ったのですが、よくよく記事を見てみると「現在プレビュー中で、MySQL Enterprise EditionとMySQL Heatwaveでのみ利用」とのことで、、、
エンタープライズ版は敷居が高そう、一方Heatwaveであれば調査した感じAWSでちょっとだけ試すこともできなくもなさそうですが、Oracle側に課金することになるためそちら側のアカウント作成も必要云々とそれなりに手間がかかりそうだと思ったので、今回は一周回って、それぞれのRDBMSにおいてこの辺どうなってるんだっけ?といった情報をまとめてみようかなと思います。
いきなり企画倒れ感ありますがよろしくお願いします。 それぞれを見てく前に先に結論だけ一覧表にしています。 ※ 補足
SQLiteでも、直接のUDF作成機能は提供していないが、組み込みを行うアプリケーションのホスト言語を通じてUDFを定義・使用することが可能。そのため多くの言語でudfの登録が可能。SQLエンジンは必要な時点で外部のランタイム(Pythonランタイムや、C/C++コードがコンパイルされたバイナリ)環境にコントロールを渡し、UDFの実行結果を受け取る。対象言語の数自体も多くなってしまうので一覧表からは省略 この一覧表を載せただけだと、テックブログとしてあまりにボリュームが無さすぎるので、一応いくつか試してみます。 シンプルな関数ですが、以下のように定義することが可能です。 [実行結果]
色々な言語で定義できるのが特徴です。以下のように実行できました。尚、MySQL時に接続を作るのが手間でターミナルから直接ログインしていましたが、それはそれでSQL書くのが面倒だったのでここからはDBeaverをクライアントツールとして使用しています。 [実行結果]
なお、前述の通りPostgreSQLはPL/hogeを導入することで様々な言語で関数の定義が可能です。 前述の通り、SQLiteでは、コマンドラインツールやSQL内で直接作成するのではなく、SQLiteを組み込んだアプリケーション内でプログラミング言語を使用して定義します。 [実行結果]
We Are Hiring! ABEJAは、テクノロジーの社会実装に取り組んでいます。 技術はもちろん、技術をどのようにして社会やビジネスに組み込んでいくかを考えるのが好きな方は、下記採用ページからエントリーください!はじめに
まとめ
MySQL
PostgreSQL
Oracle
SQLServer
SQL
◯ (ストアドファンクション)
◯
◯
◯
PL/pgSQL
◯
PL/SQL
◯
T-SQL
◯
JavaScript
△ (一部プラン)
◯ (PL/V8)
Python
◯ (PL/Python)
◯ (ML Services)
Perl
◯ (PL/Perl)
Java
◯ (PL/Java)
◯
C
◯
Tcl
◯ (PL/Tcl)
Ruby
◯ (PL/Ruby,非公式?)
PHP
◯ (PL/PHP,非公式?)
Lua
◯ (PL/Lua,非公式?)
R
◯ (ML Services)
ちょっと試してみる
MySQL
delimiter //
CREATE FUNCTION classify_number(num INT) RETURNS VARCHAR(10)
DETERMINISTIC
BEGIN
DECLARE result VARCHAR(10);
IF num < 10 THEN
SET result = 'Small';
ELSEIF num < 100 THEN
SET result = 'Middle';
ELSE
SET result = 'Large';
END IF;
RETURN result;
END;
//
PostgreSQL
CREATE OR REPLACE FUNCTION classify_number(num INT) RETURNS VARCHAR(10)
AS $$
BEGIN
IF num < 10 THEN
RETURN 'Small';
ELSIF num < 100 THEN
RETURN 'Middle';
ELSE
RETURN 'Large';
END IF;
END;
$$ LANGUAGE plpgsql;
SQLite
import sqlite3
# データベースに接続
conn = sqlite3.connect('mydatabase.db')
# カーソルの作成
c = conn.cursor()
def classify_number(num):
if num < 10:
return 'Small'
elif num < 100:
return 'Middle'
else:
return 'Large'
# Python関数をSQLiteのUDFとして登録
conn.create_function("classify_number", 1, classify_number)
# UDFを使用するSQLクエリの実行
c.execute("SELECT classify_number(38)")
print(c.fetchone())
# コネクションのクローズ
conn.close()
さいごに