0

PHPで書くのは初めてで、 $mysqli->prepare() 関数を使用してステートメントを実行できるようにしていますが、失敗し続け、その理由がわかりません。$mysqli->error 内のエラーは「テーブルが使用されていません」であり、それに関する多くのドキュメントも見つからないようです...誰かが助けてくれれば、それは大歓迎です。以下のコード:

$datasqli=new mysqli(HOST, USERNAME, PASSWORD, DATABASE); // defined elsewhere
if ($datasqli->connect_errno) {
    printf("Connect failed: %s\n", $datasqli->connect_error);
    exit();
}

if ($usertest = $datasqli->prepare("INSERT INTO eeg (Identifier) 
    SELECT * FROM (SELECT ? ) AS tmp WHERE NOT EXISTS (
    SELECT Identifier FROM eeg WHERE Identifier = ?
    ) LIMIT 1")) {
    // this stuff never gets executed...
} else {
    echo $datasqli->error; // "no table used"
}

そのコード ブロックを mysql 環境内で直接実行しようとしましたが、正常に動作します。

4

1 に答える 1

2

どうやら、

SELECT * FROM (SELECT ? )

...有効な MySQL 構文として認識されません。テーブル名がありません。

編集、あなたのコメントについて:

まず、このステートメントをコンソール?で定数に置き換えて実行しても状況がエミュレートされないことに注意してください。そのため、結果を比較するには無効と見なします。

しかし、繰り返しになりますが、置換せず?に実行すると、当然、エラーが発生します。

これは、選択だけを実行することは状況に関係がないためです。あなたのphpコードでは、失敗するのは実行ではなく準備です。したがって、コンソールを使用してこれをエミュレートする適切な方法は、PREPAREステートメントになります。

だから、

PREPARE myStmt 
  FROM 'SELECT * FROM (SELECT ? ) AS tmp WHERE NOT EXISTS (
    SELECT Identifier FROM eeg WHERE Identifier = ?
    ) LIMIT 1'

問題をより正確に再現します。

今、に現れるPREPAREパラメーター化されたネストされたクエリを理解するのが難しいようです。次の例を見てください。FROM

PREPARE myStmt FROM "select * from (select ? from eeg) tmp"; 

(動作しません)

PREPARE myStmt FROM "select *,? from (select * from eeg) tmp"; 

(作品)

PREPARE myStmt FROM "select *,? from (select 'asdf') tmp"; 

(作品)

PREPARE myStmt FROM "select * from eeg where Identifier in (select ?)"; 

(作品)

興味深い動作ですが、ネストさSELECTれたFROM句にパラメータがある場合、MySQL はステートメントを準備するための手がかりを欠いているとしか推測できません。

私の提案に関しては、あなたがやろうとしていることを理解していれば、ネストされた選択にパラメーターは必要ありません。のために、それを外側に移動して、ネストされた選択で定数をハードコードすることができますFROM。次のコード

if ($usertest = $datasqli->prepare("INSERT INTO eeg (Identifier) 
    SELECT ? from (select 1) tmp WHERE ? NOT IN
      (SELECT Identifier FROM eeg WHERE Identifier = ?)")) {

...トリックを行う必要があります。

于 2013-10-08T21:15:23.043 に答える