0

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 を返す方法はありますか?

4

2 に答える 2

0

ここで XMLAGG() を使用します。

begin 
return ( 
select 
    xmlelement(name "Phones", 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 

明らかに、私はあなたのデータを持っていませんが、この単純な例はアプローチが機能することを示しています:

$ db2 "create or replace function t () returns xml language sql begin \
return (select xmlagg(xmlelement(name \"tab\", tabname )) from syscat.tables \
where tabname like '%AUTH%' and tabschema = 'SYSCAT'); end"
DB20000I  The SQL command completed successfully.
$ db2 "values t()"

1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
----------------------------------------------------------------------------
<tab>COLAUTH</tab><tab>DBAUTH</tab><tab>INDEXAUTH</tab><tab>LIBRARYAUTH</tab>
<tab>MODULEAUTH</tab><tab>PACKAGEAUTH</tab><tab>PASSTHRUAUTH</tab><tab>ROLEAUTH
</tab><tab>ROUTINEAUTH</tab><tab>SCHEMAAUTH</tab><tab>SEQUENCEAUTH</tab>tab>
SURROGATEAUTHIDS    </tab><tab>TABAUTH</tab><tab>TBSPACEAUTH</tab><tab>
VARIABLEAUTH</tab><tab>WORKLOADAUTH</tab><tab>XSROBJECTAUTH</tab>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  1 record(s) selected.
于 2013-05-29T15:51:07.343 に答える