0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LaravelからMySQLのストアドファンクションの有無を調べる方法

0
Posted at

はじめに

Laravelは使用するRDBMSを選択できるようになっていますので、ファイルタイプのSQLiteとかサーバータイプのMySQLとかでも同じような操作でORMができます。
しかし、RDBMS依存のものもあり、例えばストアドプロシージャやファンクションなどを呼び出す場合などに環境によって同じように動作しないケースもあります。

例えば本番環境ではMySQLを使っていて、ストアドファンクションを呼び出すようなコードがLaravelで作成しているプロジェクトに含まれているとします。
そして、開発環境ではDBにSQLiteを使っていたり、XAMPPのMariaDBだけどファンクションをまだ実装していなかったりするとき、そのコードは実行時エラーになります。

そういうときにDBがMySQLかつストアドファンクションを実装しているかどうかを取得できたらいいですよね。
今回はそのケースでの方法を紹介します。

実装例

今回はMySQL環境で指定した名前のストアドファンクションがあればtrueを返すユーティリティ関数を実装します。
例外処理などは省略しています。

class Util{
    public static function hasStoredFunction(string $functionName): bool{
        if(DB::getDriverName() !== 'mysql'){ return false; }
        return DB::table('INFORMATION_SCHEMA.ROUTINES')
            ->where('ROUTINE_SCHEMA', DB::raw('DATABASE()'))
            ->where('ROUTINE_NAME', $functionName)
            ->where('ROUTINE_TYPE', 'FUNCTION')
            ->exists();
    }
}

使用例

例えばLaravelでCRMとかを作っていて見積一覧のページを実装しているとする。

要件

  • 本番環境のMySQLにはquotationsテーブルのレコードidを渡すとユニークな見積番号を生成するquotation_numberというファンクションが実装されている
  • EloquentORMを使って、quotationsテーブルのデータをページネーションで取得する際に、quotation_numberファンクションがMySQL上にあれば、データと共に見積番号をq_numberとして取得する。MySQLじゃなかったりファンクションが実装されていなければ取得しない

というような場合の使用例。

//~~ 略 ~~
$q = Quotations::query();
$q->select('*');
if(Util::hasStoredFunction('quotation_number')){
    $q->selectRaw('quotation_number(id) AS q_number');
}
return $q->paginate();

まとめ

  • INFORMATION_SCHEMA.ROUTINESに自作したファンクションの情報がある。
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?