1

我正在将 sqlite3 数据库转换为 mysql。

我有一个很好的 sed 命令文件,它改变了 AUTOINCREMEMT 和其他需要的东西,但我坚持最后一个:双引号。

sqlite3 转储格式:

CREATE TABLE "products" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
  "name" varchar(255), 
  "desc" varchar(255) );

INSERT INTO "products" VALUES(1,'Flux Capacitor',
  'This is the "real" thing.\nPromise!')

对于第一个语句,我可以用反引号替换所有双引号,mysql 会很高兴。

但是,我的产品信息在数据中有双引号。我怎样才能排除这些被替换?我试图只用占位符替换那些双引号,然后我可以替换所有其他双引号,然后我可以将占位符改回来,但我的 regex-fu 没有达到标准。

据我所知:

/"[^"]*"/s

...匹配双引号文本,但我不知道如何限定只匹配单引号内的双引号。

4

3 回答 3

3

我会更改 MySQL 以接受双引号作为标识符分隔符。这是标准的 SQL 行为,您可以使用 SQL 模式使 MySQL 以这种方式运行:

mysql> SET SQL_MODE = ANSI;

或者更具体地说:

mysql> SET SQL_MODE = ANSI_QUOTES;

然后 MySQL 应该了解您的数据转储。

有关详细信息,请参阅“服务器 SQL 模式”。

于 2009-08-21T19:29:24.213 回答
0

好吧,我知道如何在 PHP 中轻松解决它preg_replace_callback()


<?php

    $sql = file_get_contents('sqlite3 dump.txt');
    function callback($match) { return str_replace('"', '`', $match[0]); }
    $sql = preg_replace_callback('/CREATE TABLE .*?;/s', callback, $sql);
    echo preg_replace_callback('/INSERT INTO .*? VALUES/s', callback, $sql);

?>

除非您可以像 Bill Karwin 所说的那样“设置 SQL_MODE = ANSI_QUOTES”。

于 2009-08-21T19:45:09.470 回答
0

我可以用反引号替换所有双引号,mysql会很高兴。

现在很开心,但也解决不了问题,以后很容易摔倒。撇号和反斜杠在 MySQL 中的工作方式也不同。

我的产品信息在数据中有双引号。我怎样才能排除这些被替换?

你不能可靠。SQL 语法实际上相当复杂,一般情况下无法通过 regex hacking 进行解析。

Bill 建议更改 SQL_MODE 以适应现有语法是一种更好的方法。我一直在 ANSI 模式下运行 MySQL,因为我不喜欢将我的应用程序定制为一个特定数据库的弱点。

于 2009-08-21T19:49:52.707 回答