如何从管道分隔数据生成sql插件?

时间:2011-01-09 15:40:37

标签: elisp

以下列格式给出一组分隔数据:

1|Star Wars: Episode IV - A New Hope|1977|Action,Sci-Fi|George Lucas
2|Titanic|1997|Drama,History,Romance|James Cameron

elisp 中,如何以这种格式生成sql insert语句?

insert into table 
   values(1,"Star Wars: Episode IV - A New Hope",1977","Action,Sci-Fi","George Lucas",0);
insert into table 
   values(2,"Titanic",1997,"Drama,History,Romance","James Cameron",0);

为了简化问题,让我们允许参数告诉哪个 列是文本或数字。 (例如0,1,0,1,1)

以下是我在Perl中的表现。

my @ctypes=qw/0 1 0 1 1/;

while(<>) {
  chop;
  @F=split('\|', $_);
  print "insert into table values(";
  foreach my $col (@F) {
    my $type=shift(@ctypes);
    print ($type == 1 ? '"'.$col.'"' : $col);
    print ",";
  }

  print "0);\n";
}

2 个答案:

答案 0 :(得分:0)

你可以编写一个简单的程序来遍历每一行并查找分隔符|并生成插入语句。如果您熟悉使用mysql,可以使用“load data”命令将数据导入mysql表。你必须通过

将数据保存在文件中

答案 1 :(得分:0)

要在缓冲区末尾插入数据:

(require 'cl)
(defun* insert-statements (rows ctypes &key (table-name "table") (delimiter "|"))
  (let* ((values-template 
          (mapconcat '(lambda (type) (if (= type 1) "\"%s\"" "%s")) ctypes ","))
         (template (format "insert into %s values(%s);\n" table-name values-template)))
    (mapcar '(lambda (row) (insert (apply 'format (cons template (split-string row delimiter)))))
            rows)))

(let ((data "1|Star Wars: Episode IV - A New Hope|1977|Action,Sci-Fi|George Lucas
2|Titanic|1997|Drama,History,Romance|James Cameron")
      (ctypes '(0 1 0 1 1)))
  (save-excursion
    (goto-char (point-max))
    (insert-statements (split-string data "\n") ctypes)))

与Perl解决方案相比,此解决方案可能无法很好地扩展。

或者,我们可以使用SqlMode将值插入数据库:

(require 'cl)
(defun* insert-statements (rows ctypes &key (table-name "table") (delimiter "|"))
  (let* ((values-template 
            (mapconcat '(lambda (type) (if (= type 1) "\"%s\"" "%s")) ctypes ","))
         (template (format "insert into %s values(%s);" table-name values-template)))
    (mapcar '(lambda (row) (sql-send-string
                            (apply 'format (cons template (split-string row delimiter)))) )
            rows)))
(sql-sqlite)
(sql-send-string "create table test (id, title, yr, genre, director);")
(let ((data "1|Star Wars: Episode IV - A New Hope|1977|Action,Sci-Fi|George Lucas
2|Titanic|1997|Drama,History,Romance|James Cameron")
      (ctypes '(0 1 0 1 1)))
  (insert-statements (split-string data "\n") ctypes :table-name 'test))
(sql-send-string "select title from test;")
(sql-send-string "drop table test;")