【问题标题】:Escape MYSQL Insert from batch script从批处理脚本中转义 MYSQL 插入
【发布时间】:2014-06-17 22:59:24
【问题描述】:

MYSQL 有内置的转义机制吗?

我正在运行一些脚本并将值插入 MYSQL 数据库。监视脚本时,一切似乎都正常,打印输出显示一切正常,但是在检查数据库时,一些值以一种奇怪的方式插入,一些字母被替换为控制字符或分隔符(我正在做 set basename=!var:~7! 以获得要插入的值会出现问题)。

具体来说,小写 b 被替换为 BS char,小写 r 被替换。

由于脚本是 Windows 批处理文件,我想知道是否可以通过查询强制转义这些字符(如 PHP 中的 mysql_real_escape_string,但直接在 MYSQL 中)或设置一些选项服务器端以便数据库处理这些情况。

有什么想法吗?

【问题讨论】:

  • 你能发布一个这样被破坏的字符串的例子吗?
  • 例如set var = e:\Data\bqvr 然后set basename=!var:~7!; echo !basename! 控制台输出:bqvr MYSQL 条目:BSqbr。在这种情况下,BS 是一个字符图标。

标签: mysql batch-file escaping windows-server-2008


【解决方案1】:

你描述的是我们期望的结果,给定输入流中的反斜杠字符。

其中 '\b' 出现在字符串文字中,将被解释为退格字符。

其中 '\r' 出现在字符串文字中,将被解释为回车符。

为避免解释这些(和其他类似的)特殊“转义序列”字符,规范模式是在反斜杠字符之前加上另一个反斜杠。

其中 '\\' 出现在字符串文字中,将被解释为单个反斜杠字符。


所以,回答您的问题...是的,MySQL 有一个内置的特殊字符“转义序列”;这听起来像您遇到的问题;您的某些反斜杠字符被解释为“转义序列”。

而且,不,mysql 命令行客户端中没有选项可以执行mysql_real_escape_string 类型功能。命令行客户端在收到字符串时将其传递给服务器。

但可以将会话的sql_mode 设置为包含NO_BACKSLASH_ESCAPES 选项。这会禁用将反斜杠字符解释为特殊转义序列的开头,并且反斜杠字符将被解释为文字反斜杠字符。

查询当前会话的sql_mode

SELECT @@SESSION.sql_mode ;

设置当前sql_mode,例如

SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES'

注意:SET 语句将覆盖当前的sql_mode,而不仅仅是更改一个设置。所以你可能只想添加到现有的 sql_mode,如果它已经设置为空白以外的东西,例如

如果当前 sql_mode 设置为 'ALLOW_INVALID_DATES,ANSI_QUOTES',您只需将选项添加到当前设置,例如

SET SESSION sql_mode = 'ALLOW_INVALID_DATES,ANSI_QUOTES,NO_BACKSLASH_ESCAPES'

【讨论】:

  • 这仅适用于当前正在运行的连接,对吧(不影响服务器中运行的其他查询)?如果我有>mysql -h host -u root -ppass -e "INSERT INTO db.tab VALUES (arg1,...);",添加它会是这样吗? >mysql -h host -u root -ppass -e "SET SESSION sql_mode = 'ALLOW_INVALID_DATES,ANSI_QUOTES,NO_BACKSLASH_ESCAPES'; INSERT INTO db.tab VALUES (arg1,...);"
  • @Hito_kun:是的。 SET SESSION sql_mode只影响当前连接。 (还有一个 GLOBAL 设置,但不要更改它。)我回答中的最后一条语句是假设 sql_mode 的 current 设置是 'ALLOW_INVALID_DATES,ANSI_QUOTES' 就像一个例子。 (这就是为什么我演示了如何检索 sql_mode 的当前值,以显示您如何追加 另一个选项。如果sql_mode 当前为空,那么只需执行 SET SESSION sql_mode = 'NO_BACKSLASH_ESCAPES'。(sql_mode 的其他设置与反斜杠无关。)
  • 那么,运行这个>mysql -h host -u root -ppass -e "SET SESSION sql_mode = 'ALLOW_INVALID_DATES,ANSI_QUOTES,NO_BACKSLASH_ESCAPES'; INSERT INTO db.tab VALUES (arg1,...);" 应该可以,对吧?
  • @Hito_kun: SET sql_mode = 'NO_BACKSLASH_ESCAPES'; 就足够了。 但是,该语句将覆盖 sql_mode 的当前设置,这就是为什么了解当前设置很重要的原因。这就是为什么你想只用 SELECT @@SESSION.sql_mode; 来运行,这样你就可以看到 sql_mode 的当前设置,所以你可以添加 NO_BACKSLASH_ESCAPES 选项来那。 (sql_mode 中的其他选项是可选,并且影响行为other,而不是反斜杠的解释方式。)
猜你喜欢
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多