MySQL道普請便り

第220回MySQL Shellでプログラムファイルを使ってSQLを実行してみよう

今回は第99回 mysqlコマンドラインクライアントでSQLをファイルから実行するで紹介させていただいた、ファイルに記載した内容をMySQL Shellで実行する方法について紹介していきたいと思います。

検証環境

今回はDockerで建てたMySQLを使用します。以下のコマンドでDockerを建ててローカルからアクセスをします。

% docker run --platform linux/x86_64 -p 127.0.0.1:3307:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_USER=kk2170 -e MYSQL_PASSWORD=my-secret-pw -d mysql:8.0.36 --secure-file-priv='/tmp'

今回はテストデータとして第2回 MySQLにはじめてのデータを入れてみるで紹介されている「サンプルデータその3、KEN_ALL.CSV」のデータを利用して行うため、--secure-file-priv='/tmp'を指定しています。

コンテナ内にunzipが入っていないため、unzipからiconvまでのコマンドをローカルで行い、docker cpでファイルを事前に送り、その後LOAD DATA INFILEを実行しています。

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statementというエラーが表示された場合は、KEN_ALL_CSV_UTF8.csvを置いたファイルが--secure-file-priv='/tmp'配下にあるか確認してみてください。

今回も第215回や第214回と同様にDockerのイメージにあるMySQL Shellを使用して接続をしていきます。まずは、対話モードでも実行を行いたいので対話モードでJavaScriptを実行します。

立ち上げたDockerコンテナの中に入るためにコンテナIDを調べます。

$  docker ps
CONTAINER ID   IMAGE                               COMMAND                  CREATED          STATUS
     PORTS                                                 NAMES
5480636b729f   mysql:8.0.36                        "docker-entrypoint.s…"   12 seconds ago   Up 10 seconds
     33060/tcp, 127.0.0.1:3307->3306/tcp                   elastic_lederberg

続いて、Docker execコマンドを使用してMySQLのコンテナ内部に入ります。その後、mysqlshコマンドでログインを済ませます。

$ docker exec -it 5480636b729f bash

# mysqlsh
  〈中略〉
 MySQL  localhost  JS >

中略された部分に関して詳細が知りたい場合は、第214回で説明を行っているので、そちらを参照してください。執筆時点では以下の通りMySQL 8.0.36を使用しております。

 MySQL  localhost  JS > \sql select version();
Fetching global names for auto-completion... Press ^C to stop.
+-----------+
| version() |
+-----------+
| 8.0.36    |
+-----------+
1 row in set (0.0001 sec)

バッチモードで実行してみる

さっそくですが、バッチモードで実行してみましょう。

$ cat shibuya.sql
select  zip_code from zipcode.zipcode where city like "%渋谷区%" order by zip_code;

第99回でも使用した、このSQLを実行してみましょう。このクエリは渋谷区に該当する郵便番号のデータを取得するSQLです。MySQL Shellでバッチ的に起動するには--fileオプションを付けて実行しましょう。

bash-4.4# mysqlsh --file shibuya.sql
zip_code
1500000
  〈中略〉
1510072
1510073

このように実行することができました。

SQLに関してはこんな感じで動く事がわかったのですが、では、JavaScriptとPythonはどうなるでしょうか? testという文字列を表示するprint.jsとprint.pyを用意して、それぞれ実行してみます。

bash-4.4# cat print.js
print('test')

bash-4.4# cat print.py
print('test')

それぞれ同様にprint文を実行します。print.jsから実行してみましょう。

bash-4.4# mysqlsh --file print.js
testbash-4.4#

ちょっとわかりにくいのですが、testと表示されている事がわかります。続いてpythonを実行してみましょう。

bash-4.4# mysqlsh --file print.py
test
bash-4.4#

こちらは改行されて表示されています。このように勝手に--fileオプションの引数として渡すと、拡張子を見て判定して実行してくれます。ちなみに、shibuya.sqlの⁠.sql⁠を消した状態で実行すると、デフォルトとして設定されているJavaScriptとして解釈されてエラーになります。

bash-4.4# mysqlsh --file shibuya
SyntaxError: Unexpected identifier 'zip_code' at shibuya:1:9
in select  zip_code from zipcode.zipcode where city like "%渋谷区%" order by zip_code;
           ^^^^^^^^

--fileを付けて実行する際は、拡張子はしっかりと付けましょう。

コマンドから渡す

その他にもSQLを実行する方法があります。標準入力を使って指定する方法です。

 cat shibuya.sql | mysqlsh --sql
 
zip_code
1500000
  〈中略〉
1510072
1510073

こちらはshibuya.sqlの中身を次の実行コマンドに渡していて、mysqlshは--sqlはSQLモードとして起動するという事を行っています。SQLモードとして起動するため、起動後に標準入力で渡されたSQLが実行されて結果が得られます。

同様に--py--pythonとすると、Pythonが実行できます。

bash-4.4# cat print.py | mysqlsh --py
test
bash-4.4#

このようにPythonが実行されていることがわかります。

JavaScriptがデフォルトのためあまり無いと思いますが、JavaScriptを実行したい場合は--js--javascriptをつけて実行しましょう。

bash-4.4# cat print.js | mysqlsh
testbash-4.4#

このようにJavaScriptが実行されていることがわかります。

あまり無いとは思いますが、PythonとしてもJavaScriptとしても解釈可能なプログラムを実行させようとした場合に想定していない言語で動いてしまうことを防ぐことにもつながるため、標準入力から扱う方が明示的でわかりやすいといえます。

その他、mysqlコマンドラインクライアントのように-eオプションを使って実行することもできます。

mysqlsh --sql -e 'select  zip_code from zipcode.zipcode where city like "%渋谷区%" order by zip_code;'

zip_code
1500000
  〈中略〉
1510072
1510073

-eオプションもモード指定をしないと、デフォルトに指定したモードで実行されます。特に指定が無ければJavaScriptとして実行されます。

まとめ

今回はMySQL Shellでプログラムをバッチ的に実行する方法を紹介しました。第99回のまとめでも説明させていただきましたが、運用を行う際に何らかのスクリプトファイルとして定義ができた方がレビューや実行漏れなどが少なくなるため、副作用が伴うデータベースの操作を行う際には必須となると思います。

また、複雑なSQLやちょっと保存して別の値に加工をしてUPDATEしたい場合などに、JavaScriptやPythonといったスクリプト言語が使用できる事は、かなりの強みになると思います。

MySQLの標準的な機能だけで簡易的な加工や複雑な処理が行えることにつながるので、ぜひ一度試してみてはいかがでしょうか。

おすすめ記事

記事・ニュース一覧