一次做几个修改操作
Do several modify operations at once
在下面的代码中,首先需要添加一个元素,在其余代码中创建或更新名为 t 的属性。
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify insert node <update data="{$p2}" />
as last into $p/log
return $p
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
select XMLQuery('
copy $i := $p1 modify(
if (fn:exists($i/log[1]/@t)) then (
replace value of node $i/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $i/log[1]
)
)
return $i
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
我的问题是我想像这样将两个修改合并为一个 xquery 调用
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify(
insert node <update data="{$p2}" />
as last into $p/log
)
copy $i := $p modify(
if (fn:exists($i/log[1]/@t)) then (
replace value of node $i/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $i/log[1]
)
)
return $i
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
在我看来这是正确的,但显然我遗漏了什么。还是不能在oracle xquery中完成?
给出的错误信息:
ORA-19114: XPST0003 - Error during parsing the XQuery expression:
LPX-00801: XQuery syntax error at 'copy' 7 copy $i := $p modify(
- ^ ORA-06512: em line 5
您可以在单个修改子句中组合这两个操作:
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify(
insert node <update data="{$p2}" />
as last into $p/log,
if (fn:exists($p/log[1]/@t)) then (
replace value of node $p/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $p/log[1]
)
)
return $p
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
/
<log t="19-JUN-17 21.25.56.434586 +01:00"><update data="19-JUN-17 21.25.56.434586 +01:00"/></log>
PL/SQL procedure successfully completed.
这似乎与您的原始块得到相同的结果,有或没有现有的 t
属性。
顺便说一下,您目前依靠 NLS 会话设置将时间戳格式化为字符串;最好明确地做,例如
...
' PASSING LOG_REFERENCE AS "p1",
to_char(systimestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6') AS "p2"
RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
获得类似
的输出
<log t="2017-06-19T21:28:54.896506"><update data="2017-06-19T21:28:54.896506"/></log>
在下面的代码中,首先需要添加一个元素,在其余代码中创建或更新名为 t 的属性。
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify insert node <update data="{$p2}" />
as last into $p/log
return $p
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
select XMLQuery('
copy $i := $p1 modify(
if (fn:exists($i/log[1]/@t)) then (
replace value of node $i/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $i/log[1]
)
)
return $i
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
我的问题是我想像这样将两个修改合并为一个 xquery 调用
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify(
insert node <update data="{$p2}" />
as last into $p/log
)
copy $i := $p modify(
if (fn:exists($i/log[1]/@t)) then (
replace value of node $i/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $i/log[1]
)
)
return $i
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
在我看来这是正确的,但显然我遗漏了什么。还是不能在oracle xquery中完成?
给出的错误信息:
ORA-19114: XPST0003 - Error during parsing the XQuery expression: LPX-00801: XQuery syntax error at 'copy' 7 copy $i := $p modify( - ^ ORA-06512: em line 5
您可以在单个修改子句中组合这两个操作:
declare
LOG_REFERENCE xmltype:=xmltype('<log />');
begin
select XMLQuery('
copy $p := $p1 modify(
insert node <update data="{$p2}" />
as last into $p/log,
if (fn:exists($p/log[1]/@t)) then (
replace value of node $p/log[1]/@t with $p2
) else (
insert node attribute t {$p2} into $p/log[1]
)
)
return $p
' PASSING LOG_REFERENCE AS "p1", to_char(systimestamp) AS "p2" RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
dbms_output.PUT_LINE(LOG_REFERENCE.getClobVal());
end;
/
<log t="19-JUN-17 21.25.56.434586 +01:00"><update data="19-JUN-17 21.25.56.434586 +01:00"/></log>
PL/SQL procedure successfully completed.
这似乎与您的原始块得到相同的结果,有或没有现有的 t
属性。
顺便说一下,您目前依靠 NLS 会话设置将时间戳格式化为字符串;最好明确地做,例如
...
' PASSING LOG_REFERENCE AS "p1",
to_char(systimestamp, 'YYYY-MM-DD"T"HH24:MI:SS.FF6') AS "p2"
RETURNING CONTENT)
INTO LOG_REFERENCE from dual;
获得类似
的输出<log t="2017-06-19T21:28:54.896506"><update data="2017-06-19T21:28:54.896506"/></log>