はじめに
これまで、クエリビルダやEloquentを使ってCRUD処理を行ってきたが、ストアドを呼び出しても同様の処理が行えるのか、
そもそもストアドを呼べるのか、ふと疑問に思ったので試してみた。
今回はMySQLで作成したストアドプロシージャをLaravelから実行させてみる。
環境
・Laravel 7.30.4
・MySQL 5.7.32
.envファイルの変更
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=hoge
DB_USERNAME="ユーザー名"
DB_PASSWORD="パスワード"
変更内容を反映させるために「php artisan config:clear」を忘れずに…
マイグレーションファイルの変更
今回は既存のUsersテーブルを使用し、カラムは必要最低限の「id」と「name」のみにします。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
// $table->string('email')->unique();
// $table->timestamp('email_verified_at')->nullable();
// $table->string('password');
// $table->rememberToken();
// $table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
疎通確認(マイグレーションの実行)
下記のコマンドを実行し、DB上にテーブルが生成されていればOKです。
php artisan migrate
テーブルの生成に成功したらデータを数件登録しておきましょう。
mysql> select * from users;
+----+------+
| id | name |
+----+------+
| 1 | hoge |
| 2 | huga |
| 3 | piyo |
+----+------+
3 rows in set (0.00 sec)
ストアドプロシージャの作成
MySQLで簡単なストアドプロシージャを作成します。
ただの単体のUPDATE文です。
mysql> delimiter //
mysql> create procedure hoge_procedure(in param1 int, in param2 varchar(50))
-> begin
-> update users set name = param2 where id = param1;
-> end //
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
ストアドプロシージャの実行
DBファサードのstatementメソッドを使います。
プロジェクトのディレクトリに移動し、以下のコマンドを実行します。
今回は、id=1のhogeをhogehogeに更新させたいと思います。
>>> DB::statement('CALL hoge_procedure(?, ?)', [1, 'hogehoge']);
=> true
mysql> select * from users;
+----+----------+
| id | name |
+----+----------+
| 1 | hogehoge | -- hogeからhogehogeへ更新されている
| 2 | huga |
| 3 | piyo |
+----+----------+
3 rows in set (0.00 sec)
上手くいってますね。
まとめ
ダラダラと書いて行きましたが、要するにDBファサードのstatementメソッドを使えばストアドが実行できるようです。
余談ですが、ストアドを関数インポートでモデルとして扱えたらSQLを直書きすることは無くなるのですが、Laravelでは難しいのかな。。。