sql >> データベース >  >> RDS >> Mysql

PDOプリペアドステートメントから生のSQLクエリ文字列を取得する

    パラメータ値が補間された最終的なSQLクエリが必要であることを意味していると思います。これはデバッグに役立つことは理解していますが、プリペアドステートメントが機能する方法ではありません。パラメータはクライアント側でプリペアドステートメントと結合されないため、PDOはパラメータと結合されたクエリ文字列にアクセスできないようにする必要があります。

    SQLステートメントはprepare()を実行するとデータベースサーバーに送信され、パラメーターはexecute()を実行すると個別に送信されます。 MySQLの一般的なクエリログには、execute()の後に値が補間された最終的なSQLが表示されます。以下は私の一般的なクエリログからの抜粋です。 PDOからではなくmysqlCLIからクエリを実行しましたが、原則は同じです。

    081016 16:51:28 2 Query       prepare s1 from 'select * from foo where i = ?'
                    2 Prepare     [2] select * from foo where i = ?
    081016 16:51:39 2 Query       set @a =1
    081016 16:51:47 2 Query       execute s1 using @a
                    2 Execute     [2] select * from foo where i = 1
    

    PDO属性PDO::ATTR_EMULATE_PREPARESを設定すると、必要なものを取得することもできます。このモードでは、PDOはパラメーターをSQLクエリに補間し、execute()を実行するとクエリ全体を送信します。 これは真に準備されたクエリではありません。 execute()の前に変数をSQL文字列に補間することにより、準備されたクエリの利点を回避します。

    @afilinaからのコメントを再確認してください:

    いいえ、テキストSQLクエリはではありません 実行中にパラメータと組み合わされます。したがって、PDOが表示するものは何もありません。

    内部的には、PDO ::ATTR_EMULATE_PREPARESを使用する場合、PDOはSQLクエリのコピーを作成し、準備と実行を行う前にパラメータ値をその中に補間します。ただし、PDOはこの変更されたSQLクエリを公開しません。

    PDOStatementオブジェクトにはプロパティ$queryStringがありますが、これはPDOStatementのコンストラクターでのみ設定され、クエリがパラメーターで書き換えられても更新されません。

    書き直されたクエリを公開するようにPDOに依頼することは、PDOにとって妥当な機能要求です。ただし、それでも、PDO ::ATTR_EMULATE_PREPARESを使用しない限り、「完全な」クエリは得られません。

    これが、MySQLサーバーの一般的なクエリログを使用する上記の回避策を示している理由です。この場合、パラメータープレースホルダーを使用して準備されたクエリでさえ、サーバー上で書き換えられ、パラメーター値がクエリ文字列に埋め戻されます。ただし、これはロギング中にのみ実行され、クエリの実行中には実行されません。



    1. SQLServerシステムデータベースのメンテナンス

    2. OracleテーブルのExcelワークシートへのエクスポート

    3. SQLリファレンステーブル:基本的なクエリを作成および作成する方法

    4. MySQL、1つのクエリで複数のテーブルを更新