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 を実行すると、予想どおり、2 行のデータが正しく取得されます。
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;
これらは、私が期待したとおりに返された 2 行のデータです。
<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 の場合、基本述語の副選択によって複数の行が生成されています。1 行のみが許可されます。回復 。. . 処置: 1つの結果行のみが返されるように選択を変更してから、リクエストを再試行してください。複数の結果行を処理するには、DECLARE CURSOR、OPEN、および FETCH ステートメントを使用する必要があります。サブクエリの場合、IN、EXISTS、ANY、または ALL 述語を使用して、複数の結果行を処理できます。1 行が予期されていた場合、重複行などのデータ エラーが発生している可能性があります。
**期待どおり、データのすべての行を xml コードの 1 つのブロックとして返すように、この関数を修正するにはどうすればよいですか?
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_entity_phones(bigint(e.entityid)) のような関数呼び出しを使用して、電話セクション xml 全体を構築したいと考えていました。
OK、関数を 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 を返す方法はありますか?