カラム名に予約語を含むモデルのクエリービルダーを作る
概要
- あるモデルのカラム名が
order
のような予約語の場合、クエリービルダー生成時にMySQLのエラーが起きる app.php
や.env
中のquoteIdentifiers
をtrue
にすることでエスケープできるが、一部のクエリが書けなくなる- クエリービルダー経由でも意外と簡単に書ける
設定ファイルでの対応
以下2ファイルのquoteIdentifiers
をfalse
からtrue
に変えた
(app.php
だけでいいのかも)
# .env # Uncomment these to define database configuration via environment variables. #export DATABASE_URL="mysql://my_app:secret@localhost/${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=true&persistent=false" #export DATABASE_TEST_URL="mysql://my_app:secret@localhost/test_${APP_NAME}?encoding=utf8&timezone=UTC&cacheMetadata=true"eIdentifiers=true&persistent=false" # app.php /** * Set identifier quoting to true if you are using reserved words or * special characters in your table or column names. Enabling this * setting will result in queries built using the Query Builder having * identifiers quoted when creating SQL. It should be noted that this * decreases performance because each query needs to be traversed and * manipulated before being executed. */ 'quoteIdentifiers' => true,
これでエラーは解消される。
が、以下のようなクエリーは発行できなくなる。
$query = $this->find(); # $thisはモデル $query ->select([ 'girl_id' => 'CASE TableItems.item_type WHEN 2 THEN TableItemBacks.girl_id ELSE TableItems.girl_id END', # 中略 ])
quoteIdentifiers=false
だとSQLを展開してくれるんだけど、
true
だとCASE句がまるまるエスケープされてエラーに...。
クエリービルダーでの対応
こんな感じでクエリを作る。 予約語をエスケープするためにバッククオートを付ける
$query = $this->query(); $query->insert(['id', '`order`']); # 予約語のorderに``を付けた $query->values(['id' => 1, 'order' => 1]); $query->execute(); # 発行SQL 'INSERT INTO target_tables (id, `order`) VALUES (:c0, :c1)'