(2023年5月)
SQL文内でLIMITを変数にするとエラーになる事案。
↑ エラー ↑

確か、以前もコレで「?」となッたンで、書ゐておく。
−−−−−
以下は、idの条件を変数($id)にしており、1200は整数型ではないが、問題なく通る。
1200が整数型ではないのは、「"」(ダブルクォーテーション)や「'」(シングルクォーテーション)で囲っているから。
以下のように囲わないか、
以下のように、囲っていても、キャスト演算子で(強引に)変換すれば、整数型となる。
また、「`」(バッククォート,Shift+@)内でも変数は使えるので、テーブル名を動的に変えることもできる。
この場合は、二重に囲う(`'$table_name'`)とエラーとなる。
さて、ここからが本題。
同様に、LIMITの指定を変数にすると、それが整数型であってもエラーとなる。
↑ エラー ↑
この場合は、$limitを囲わなければ通る。
これは、LIMITには数値しか許されないが、囲うことで$limitが文字列になってしまうからという理解でOK?
だが、$limitを囲わなければ、文字列型でも通るのはなンで?
なお、以下のように$limitを外に出して「.」で結合すれば通るし、これも、$limitが文字列型であっても通る。
まぁ、コレはごッつダサゐンでヤランけど。
SQL文内に複数の変数を使用することもあるが、全て「'」で囲っているので、LIMIT時にハマッちまうのだ。
というか、SQL文内の変数は囲わないのがデフォ?
まぁ、「LIMITだけクセモノなンで妖虫遺!!」というコトだけ記憶しておけばゐ々ンかはシラン(SILANE)。
てコトで、プリペアドステートメントのbindValueでアレするかね...
bindValueを使うと、$limitはシングルクォーテーションで囲わないので、数値で通るハヅ。
これを使うと、NULL(ヌルゥ!)を入れたいのに、NULLが「'NULL'」により文字列になって入らない!というのも回避できる。
なお、bindValueは変数/値ともに入るが、bindParamは変数のみなので注意。
bindValueは即座に変数を評価し、bindParamはその後のexecuteされた時点で変数を評価する。
関連:[怪奇文] MySQLのINのヴァクァ詐加減www [ゐクァれ]
関連:[MySQL] テーブルのエクスポートで、レコード数の不一致が生じる問題 [phpMyAdmin,Dump all rows]
関連:[MySQL] ランキングなどで順位を取得する方法 [自己結合]
関連:[MySQL] idを詰める(連番を振り直す)方法
関連:[MySQL] index定義の無駄と、indexが役に立たない場合 [悪例,アンチパターン]
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を詰める(連番を振り直す)方法
関連:[MySQL] index定義の無駄と、indexが役に立たない場合 [悪例,アンチパターン]
[PR] au PAY / au WALLET カード 情報








コメント