LoginSignup
2
2

More than 3 years have passed since last update.

Laravel+OracleのクエリビルダでLIMIT句のtake()が使えないときの代用表記

Last updated at Posted at 2019-06-19

環境

CentOS 7
PHP 7.3
Laravel 5.8
Oracle 11g ←バージョンがかなり古いので、以下は最新のOracleには当てはまらない可能性があります
oci8 2.2

困っていたこと

mySQLなどを使っているとき、Laravelのクエリビルダで結果をn件だけ取得したい場合、以下のような感じで実現できます。
公式リファレンス通りですね。

DB::table('テーブル名')->take(件数)->get();

※公式リファレンスの該当部分: https://readouble.com/laravel/5.8/ja/queries.html

しかし、現在oci8とlaravel-oci8を使ってOracleに接続しているのですが、上の書き方だと以下のようなQueryExceptionが出てしまいました。

Error Code : 918 Error Message :
ORA-00918: column ambiguously defined Position : ●● Statement : (以下略)

調べてみると、OracleにはLIMITOFFSETが存在しないらしいです。
そのためtake()では有効なSQLが発行できず、エラーになってしまっているのか?と予想しました。(このあたり調査不足)

対策を探す

OracleのSQLを直接書く場合、ROWNUMという値をカラムのような形で使用して取得件数を制御できるらしく、
具体的にはwhere句でROWNUM = nなどとすることで件数を指定できるようです。=だけでなく不等号も使えるっぽいです。
そこで試しに1件だけ取得しようと、クエリビルダで

DB::table('テーブル名')->where('ROWNUM', 1)->get();

DB::table('テーブル名')->where('ROWNUM', '1')->get();

といった形を試してみたのですが、エラーが無くなりません。
原因は分かりませんでした。もしかするとROWNUMが擬似カラムだからでしょうか。

最終的には

DB::table('テーブル名')->whereRaw('ROWNUM = 1')->get();

のように、WHERE句の中身を直接記載することで取得できました。
(1の部分は実際には可変なので、ROWNUM =と数字を結合した文字列をwhereRaw()に読ませています)
 

2
2
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
2
2