Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

環境

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()に読ませています)
 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away