sample_dbデータベースの中に1という名称のテーブルを設定しております。数値列でテーブル名を指定することはMYSQLでは禁じられていないと思います。ただ、SQL文を書くときにデータベース名を明示的に書かなければエラーになることがわかりました。
php
1$sql = "SELECT * FROM 1 WHERE category_1 = 1 AND category_2 = 1 AND status = 1 AND ver = (SELECT MAX(ver) FROM 1)"; 2 3//Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1 WHERE category_1 = 1 AND category_2 = 1 AND status = 1 AND ver = (SELECT MAX(v' at line 1 in /Applications/MAMP/htdocs/textile/dist/51_class.php on line 38
このようにテーブル名を単純に1を指定するとエラーが出力されるため、以下のように明示的に書き換えると動作することが確認できました。
php
1$sql = "SELECT * FROM sample_db.1 WHERE category_1 = 1 AND category_2 = 1 AND status = 1 AND ver = (SELECT MAX(ver) FROM sample_db.1)";
これを前提に、PDO::prepareを利用(テーブル名についてプレースホルダをおいて、値をバインドする)すると以下のようなエラーが出力されてしまいます。
php
1$id = 1; 2$id_sub1 = 2; 3$id_sub2 = 3; 4$sql = "SELECT * FROM sample_db.? WHERE category_1 = ? AND category_2 = ? AND status = 1 AND ver = (SELECT MAX(ver) FROM sample_db.?)"; 5$stmt = $pdo->prepare($sql); 6$stmt->bindValue(1,$id); 7$stmt->bindValue(2,$id_sub1); 8$stmt->bindValue(3,$id_sub2); 9$stmt->bindValue(4,$id); 10$stmt->execute(); 11$result = $stmt->fetch(); 12 13//Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? WHERE category_1 = ? AND category_2 = ? AND ver = (SELECT MAX(ver) FROM sample_db' at line 1 in /Applications/MAMP/htdocs/textile/dist/1_main.php:61 Stack trace: #0 /Applications/MAMP/htdocs/textile/dist/1_main.php(61): PDO->prepare('SELECT contents...') #1 {main} thrown in /Applications/MAMP/htdocs/textile/dist/1_main.php on line 61
sample_db.?のような指定の仕方がprepareステートメントでは認められないのか、Fatal errorの理由がわからず行き詰まってしまいました。どのように解決しうるか、アドバイスをいただけるとありがたいです。
【追記】
諸々記事を検索をしていたらテーブル名にはプリペアステートメントが利用できないようなものを見つけました。(例)解決策としてprepareを使わずにsql文に直接変数を入れるような方法ばかり見つかるのですが、インジェンクション対策的に受け入れられない方法かと思うのですが、DByaテーブルの構造から見直すしかないのでしょうか?
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/07/30 22:57 編集
2021/07/30 23:05
2021/07/31 00:20