在 SQL 中,我需要创建如下所示的 xml 代码:
<Phone>
<PhoneTypeCode tc="12">Mobile</PhoneTypeCode>
<Area>801</Area>
<DialNumber>9996666</DialNumber>
</Phone>
<Phone>
<PhoneTypeCode tc="2">Business</PhoneTypeCode>
<Area>801</Area>
<DialNumber>1113333</DialNumber>
</Phone>
当我运行这个 sql 时,我正确地得到了两行数据,正如我所期望的:
select
xmlelement(
Name "Phone",
xmlelement(
name "PhoneTypeCode",
xmlattributes(
trim(p1.phtype) as "tc"
),
trim(p1.desc)
),
xmlelement(name "AreaCode", p1.area),
xmlelement(name "DialNumber", p1.phone)
) as xml
from phone as p1 where p1.entityid = 256285;
这些是我得到的两行数据,完全符合我的预期:
<Phone><PhoneTypeCode tc="12">Mobile</PhoneTypeCode><AreaCode>351</AreaCode> <DialNumber>4443333</DialNumber></Phone>
<Phone><PhoneTypeCode tc="2">Business</PhoneTypeCode><AreaCode>351</AreaCode><DialNumber>3911111</DialNumber></Phone>
但是,当我尝试将相同的代码放入函数并调用此函数时,我收到此错误:
SQL 状态:21000 供应商代码:-811 消息:[SQL0811] SELECT 的结果超过一行。原因 。. . . . : SELECT INTO 语句、子查询或 SET 语句的子选择的结果表包含多于一行。错误类型为 2。如果错误类型为 1,则 SELECT INTO 语句尝试返回多于一行。如果错误类型为 2,则基本谓词的子选择已生成多行。只允许一行。恢复 。. . :更改选择以便只返回一个结果行,然后再次尝试请求。DECLARE CURSOR、OPEN 和 FETCH 语句必须用于处理多个结果行。对于子查询,IN、EXISTS、ANY 或 ALL 谓词可用于处理多个结果行。如果预期为一行,则可能存在数据错误,例如重复行,
**如何修复此函数,以便它将所有数据行作为我期望的一个 xml 代码块返回?
CREATE or replace FUNCTION xml_entity_phones (
#Entity_ID bigint)
RETURNS xml
LANGUAGE SQL
NOT DETERMINISTIC
reads SQL DATA
RETURNS NULL ON NULL INPUT
NO EXTERNAL ACTION
ALLOW PARALLEL
NOT FENCED
begin
return (
select
xmlelement(
Name "Phone",
xmlelement(
name "PhoneTypeCode",
xmlattributes(
trim(p.phtype) as "tc"
),
trim(p.desc)
),
xmlelement(name "AreaCode", p.area),
xmlelement(name "DialNumber", p.phone)
) as xml
from phone p where p.entityid = #entity_id
);
end
;
调用此函数的程序正在构建一个包含不同类型手机的 xml 文件,我想使用上述函数构建该文件。
最终目标是拥有一个如下所示的 xml 文档(有效与否):
<TXLife>
<TXLifeRequest>
<OLife>
<Person>
<Phone>
<PhoneTypeCode tc="12">Mobile...
<Area...
<DialNumber...
</Phone>
<Phone>
<PhoneTypeCode tc="2">Business...
<Area...
<DialNumber...
</Phone>
...
我希望使用如下函数调用来构建整个电话部分 xml:xml_entity_phones(bigint(e.entityid))。
好的,我用 xmlagg() 将函数更改为如下所示:
begin
return (
select
xmlagg(
xmlelement(
Name "Phone",
xmlelement(
name "PhoneTypeCode",
xmlattributes(
trim(p.phtype) as "tc"
),
trim(p.desc)
),
xmlelement(name "AreaCode", p.area),
xmlelement(name "DialNumber", p.phone)
)
) as xml
from phone p
where p.entityid = #entity_id
);
end
但是现在当我用 values(xml_entity_phones(256285)); 调用函数时,我得到 ++++++++++++++++。当我调用调用这个函数的过程时,我得到这个错误:
SQL 状态:22023 供应商代码:-802 消息:[SQL0802] 数据转换或数据映射错误。原因 。. . . . : 已发生错误类型 10 10 -- 用户定义的函数返回映射错误。
我确实注意到,当我按照以下几个答案中的建议使用 xmlagg 包含一个额外的 Phones 元素时,它确实成功返回了 xmlagg() 结果。但是我不能拥有电话的额外元素,因为它违反了我需要遵守的标准。
有没有办法在没有额外层的情况下返回 xmlagg?