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

XQuery to generate DROP TABLE IF EXISTS + INSERT INTO statements

我正在使用 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';

一切都很好,很漂亮。但是我想输出一些文本 before 和一次 after 所有这些语句,即 first:

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 中要困难得多,尤其是对于像我这样的非高级用户。

FLOWR 表达式在输出 XML 时看起来非常简单和合乎逻辑,但我不知道如何将累积的 return 与其他两个字符串连接起来。

任何指点将不胜感激。

我经常使用 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 )   

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

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 },
   ...
)