如何更新其他数据库中的节点或如何更新外部节点?-XDMP-UPEXTNODES

时间:2018-07-16 07:54:23

标签: xquery marklogic

我正在尝试在与当前数据库不同的数据库中更新文档。但这给了我下面的错误-

XDMP-UPEXTNODES: xdmp:node-replace(fn:doc("/C:/Users/Downloads/abc.csv-0-2")/*:envelope/*:root/*:Status, <Status>1000</Status>) -- Cannot update external nodes

我正在使用下面的代码-

let $temp := 
  for $i in $result
  let $error := $i/*:envelope/*:ErrorMessage
  let $status := $i/*:envelope/*:Status
  return 
    if(fn:exists($i) eq fn:true()) then (
      xdmp:invoke-function(
        function() { 
          xdmp:node-replace($status,<Status>1000</Status>),
          xdmp:node-replace($error,<ErrorMessage>Change Error in other Database-2</ErrorMessage>)  
        },
        <options xmlns="xdmp:eval">
          <database>{xdmp:database("DATABASE-2")}</database>
        </options>))
    else ()

我想更新 Database-2 的“错误和状态”节点。

$ result是我从 Database-2 中获取的文档。

我正在从 Database-1

运行此代码

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

您不能将数据库节点作为变量来进行更新。相反,您应该遍历数据库uri,并在要调用的函数中获取要更新的元素的新副本。也许您可以在所调用的函数中添加更多逻辑以使其变得更容易。像这样:

for $i in $result
let $uri := xdmp:node-uri($i)
return xdmp:invoke-function(function() {
  let $doc := fn:doc($uri)
  let $error := $doc/*:envelope/*:ErrorMessage
  let $status := $doc/*:envelope/*:Status
  return if(fn:exists($doc) eq fn:true()) then (
    xdmp:node-replace($status, <Status>1000</Status>),
    xdmp:node-replace($error, <ErrorMessage>Change Error in other Database-2</ErrorMessage>)
  ) else ()
}, map:entry("database", xdmp:database("DATABASE-2")))

但是要小心。听起来$ i也指向了Database-2中的实际文档,并且很容易导致死锁。调用查询可能在$ i上设置了读取锁定,导致被调用的函数无法对其进行更新。

HTH!