[MySQL] LIMITを変数にするとエラー [数値のみ可]

この記事は約4分で読めます。
スポンサーリンク

当サイトには広告が含まれています。

(2023年5月)

SQL文内でLIMITを変数にするとエラーになる事案。

$sql = "SELECT * FROM `テーブル名` ORDER BY `id` DESC LIMIT '$limit'" ;
↑ エラー ↑

妖虫

確か、以前もコレで「?」となッたンで、書ゐておく。

-----

以下は、idの条件を変数($id)にしており、1200は整数型ではないが、問題なく通る。

$id = "1200" ;

print gettype($id) ; ← string(文字列型)

$sql = "SELECT * FROM `テーブル名` WHERE `id` >= '$id' ORDER BY `id` DESC LIMIT 10" ;

1200が整数型ではないのは、「”」(ダブルクォーテーション)や「’」(シングルクォーテーション)で囲っているから。

以下のように囲わないか、

$id = 1200 ;

以下のように、囲っていても、キャスト演算子で(強引に)変換すれば、整数型となる。

$id = (int)"1200" ;
$id = (int)'1200' ;

また、「`」(バッククォート,Shift+@)内でも変数は使えるので、テーブル名を動的に変えることもできる。

$table_name = "test_table" ;
$sql = "SELECT * FROM `$table_name` WHERE `id` >= '$id' ORDER BY `id` DESC LIMIT 10" ;

この場合は、二重に囲う(`’$table_name’`)とエラーとなる。

さて、ここからが本題。

同様に、LIMITの指定を変数にすると、それが整数型であってもエラーとなる。

$limit = 10 ;

print gettype($limit) ; ← integer(整数型)

$sql = "SELECT * FROM `テーブル名` ORDER BY `id` DESC LIMIT '$limit'" ;
↑ エラー ↑

この場合は、$limitを囲わなければ通る。

$sql = "SELECT * FROM `テーブル名` ORDER BY `id` DESC LIMIT $limit" ;

これは、LIMITには数値しか許されないが、囲うことで$limitが文字列になってしまうからという理解でOK?

だが、$limitを囲わなければ、文字列型でも通るのはなンで?

なお、以下のように$limitを外に出して「.」で結合すれば通るし、これも、$limitが文字列型であっても通る。

$sql = "SELECT * FROM `テーブル名` ORDER BY `id` DESC LIMIT ".$limit ;

まぁ、コレはごッつダサゐンでヤランけど。

SQL文内に複数の変数を使用することもあるが、全て「’」で囲っているので、LIMIT時にハマッちまうのだ。

というか、SQL文内の変数は囲わないのがデフォ?

まぁ、「LIMITだけクセモノなンで妖虫遺!!」というコトだけ記憶しておけばゐ々ンかはシラン(SILANE)。

プリペアドステートメント

てコトで、プリペアドステートメントのbindValueでアレするかね…

$sql = "SELECT * FROM `テーブル名` ORDER BY `id` DESC LIMIT :limit" ;

$stmt = $pdo -> prepare($sql);
$stmt -> bindValue(":limit",$limit) ;
$stmt -> execute() ;

bindValueを使うと、$limitはシングルクォーテーションで囲わないので、数値で通るハヅ。

これを使うと、NULL(ヌルゥ!)を入れたいのに、NULLが「’NULL’」により文字列になって入らない!というのも回避できる。

なお、bindValueは変数/値ともに入るが、bindParamは変数のみなので注意。

bindValueは即座に変数を評価し、bindParamはその後のexecuteされた時点で変数を評価する。

関連:[怪奇文] MySQLのINのヴァクァ詐加減www [ゐクァれ]

関連:[MySQL] テーブルのエクスポートで、レコード数の不一致が生じる問題 [phpMyAdmin,Dump all rows]

関連:[MySQL] ランキングなどで順位を取得する方法 [自己結合]

関連:[MySQL] idを詰める(連番を振り直す)方法とAUTO_INCREMENTのリセット [DB]

関連:[MySQL] index定義の無駄と、indexが役に立たない場合 [悪例,アンチパターン]

タイトルとURLをコピーしました