XQuery生成DROP TABLE IF EXISTS + INSERT INTO语句

时间:2016-10-21 16:52:27

标签: mysql xquery xquery-3.0

我正在使用XQuery查看一堆XML文件并提取索引条款并将它们转换为SQL插入语句。这非常简单:

xquery version "3.0";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "text";
for $index in collection(/db/letters/)//index/text()
return 
    concat("INSERT INTO `indices` SET index='", $index, "';")

这会生成如下语句:

INSERT INTO `indices` SET index='foo';
INSERT INTO `indices` SET index='bar';

这一切都很好,花花公子。但我希望在之前输出一些文本,在之后输出所有这些语句,即第一次:

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `indices`
-- ----------------------------
DROP TABLE IF EXISTS `indices`;
CREATE TABLE `indices` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `norm` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=COMPACT;

,最后,

SET FOREIGN_KEY_CHECKS = 1;"

在PHP中,这将是一个非常明智的选择,但在XQuery中,它更加困难,特别是对于像我这样的非高级用户。

输出XML时,FLOWR表达式看起来非常简单和合乎逻辑,但我无法弄清楚如何使用其他两个字符串来连接累积返回值。

任何指针都将受到热烈欢迎。

1 个答案:

答案 0 :(得分:2)

我经常使用XQuery来做这件事。有时候有必要记住,XQuery实际上是关于序列的,而FLOWR表达式只是生成序列的一种方式。有几种方法可以实现您的尝试。示例如下。

xquery version "3.0";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "text";
let $newline := '
'
let $beginning :=
    ( "your first line",
      "your second line",
      "your third line",
      ...)
let $middle :=
   for    $index in collection(/db/letters/)//index/text()
   return concat("INSERT INTO `indices` SET index='", $index, "';")
let $end := ( "your first end line", "your second end line", ... )
return
   string-join( ($beginning, $middle, $end), $newline )   

或类似:

let $newline := '
'
let $lines :=
(
    ( "your first line",
      "your second line",
      "your third line",
      ...),
    (for    $index in collection(/db/letters/)//index/text()
     return concat("INSERT INTO `indices` SET index='", $index, "';")
    ),
    ( "your first end line", "your second end line", ... )
)
return string-join( $lines, $newline )   

或某些处理器将允许您使用语法创建文本节点,以便您的查询可以生成一系列文本节点,每个节点的末尾都有换行符。但请注意,text {}元素中的序列可能会以制表符分隔输出,因此在下面的示例中,换行符之前可能会有一个制表符。这可以通过concat()在text {}节点中的所有内容来克服。

let $newline := '
'
return
(  text{ 'your first line', $newline },
   text{ 'your second line', $newline },
   text{ '...', $newline },
   (for   $index in collection(/db/letters/)//index/text()
    return text{concat("INSERT INTO `indices` SET index='", $index, "';"),$newline}
   ),
   text {"your first end line", $newline },
   text {"your second end line", $newline },
   ...
)