当前位置: 首页 > 面试题库 >

从PDO准备好的语句获取原始SQL查询字符串

卫博学
2023-03-14
问题内容

在准备好的语句上调用PDOStatement :: execute()时,有没有办法使原始SQL字符串执行?对于调试目的,这将非常有用。


问题答案:

我假设您的意思是您想要最终的SQL查询,并将参数值插入其中。我知道这对调试很有用,但是它不是准备好的语句的工作方式。参数不会在客户端与预准备的语句组合,因此PDO绝对不能访问与其参数组合的查询字符串

当您执行prepare()时,SQL语句将发送到数据库服务器,而当您执行execute()时,将分别发送参数。MySQL的常规查询日志的确显示了最终SQL,其中包含在execute()之后插入的值。以下是我的一般查询日志的摘录。我从mysql
CLI(不是从PDO)运行查询,但是原理是相同的。

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 ::
ATTR_EMULATE_PREPARES,否则即使那样也不会给您“完整”的查询。

这就是为什么我显示了上面使用MySQL服务器的常规查询日志的解决方法的原因,因为在这种情况下,即使是带有参数占位符的准备好的查询也会在服务器上重写,并将参数值回填到查询字符串中。但这仅在日志记录期间完成,而不在查询执行期间完成。



 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : 从PDO准备好的语句中获取原始SQL查询字符串 (16个答案) 5个月前关闭。 有没有一种方法可以检索用于生成PDO Prepared语句对象的查询? 问题答案: 尝试$ statement-> queryString 。

  • 问题内容: 我知道准备好的语句的功能,但是我不能在这里使用它。我通过HTTP(而不是通过JDBC)将sql查询发送到外部服务器。如何对SQL查询进行转义字符串?有没有办法通过JDBC做到这一点?还是我应该为此使用自定义类/函数? ps另外,我已经连接到其他数据库,因此可以使用JDBC函数。 问题答案: 这听起来很不安全。如果要通过HTTP发送SQL语句,则可能会受到中间人攻击(以及其他攻击)的危害

  • 问题内容: 今天有人告诉我,我确实应该在应用程序中使用PDO和准备好的语句。在我了解好处的同时,我也在努力了解如何将其实现到我的工作流程中。除了它使代码更简洁外,我是否应该有一个特定的数据库类来容纳所有准备好的语句,还是应该在每次运行查询时都创建一个?我发现很难理解何时应使用标准PDO查询以及何时应使用准备好的语句。任何示例,技巧或教程链接将不胜感激。 问题答案: pdo :: prepare()

  • 问题内容: 我对C#中的准备好的语句有疑问: (当然,电子邮件包含有效的电子邮件地址,带有@符号)。 此代码返回一个随机错误- “”连接已被禁用“ {”错误[01000] [Microsoft] [ODBC SQL Server驱动程序] [TCP / IP套接字] ConnectionWrite(send())。错误[08S01] [Microsoft] [ODBC SQL Server驱动程序

  • 我有一个类,其中我使用旧的jdbc方法创建了到h2数据库的连接,该方法编写url并获取连接,我在数据库中创建了一个表,这个表不是java对象,所以我用尽了聪明的方法来为我的方法编写测试 //我还创建了一个表app_user公共void addUser(连接连接,字符串登录,字符串密码,字符串描述)抛出SQLException{ 而我的测试方法看起来像这样,有没有办法让它不那么整洁,更简单,我试图用