Oracle 10gR2を使用して、標準のリレーショナルテーブルに格納されているデータから次の疑似例のようなものを作成する必要があります。
<product>
<productName>p1</productName>
<productNumber>100</productNumber>
<productObsoletes>
<obsoletedProduct label=1>50</obsoletedProduct>
<obsoletedProduct label=2>55</obsoletedProduct>
</productObsoletes>
</product>
問題は、データを含む行を使用して意思決定を行う必要があることです。私のデータベース(私が継承したもの)は設計が不十分であり、行を含めるかどうかを決定するために必要なロジックは複雑です。残念ながら、データベースの再設計はオプションではありません。ここではロジックを大幅に単純化しているので、単純な結合やwhere句を使用できるわけではありません。データとデータ形式の定義には複雑な階層があります。
疑似コードでは、過度に単純化された決定は次のようになります。
BEGIN
--select our basic attributes
select XMLEMENT("product",XMLELEMENT("productName",name),XMLELEMENT("productNumber",product_number))
into xml_output from products where product_number = 100;
--now process our obsolete rows
select XMLELEMENT("productObsoletes") into xml_output from dual;
FOR c_row in (select * from product_obsoletes where id=100)
LOOP
IF c_row.display = 'YES' THEN
select XMLELEMENT("obsoletedProduct", XMLATTRIBUTES(c_row.label as "label"), c_row.obsoleted_product_id) into xml_output from dual;
ELSE
CONTINUE;
END IF;
END LOOP;
END;
明らかに、これは機能しません。まず、XMLElementは常に終了タグを付けるため、すべての要素を含む単一のselectステートメントを作成できない限り、それは機能しません。次に、この例では、前のXMLELEMENT出力を上書きします。XMLELEMENTがすでにタグを閉じているため、連結できません。
この時点で考えられる唯一の解決策は、必要なさまざまなXMLElementピースをさまざまなVARCHARSに選択し、文字列操作関数を使用して、さまざまなピースを挿入する適切な場所を見つけることです。大文字で醜い-U。
別の解決策はありますか?XMELEMENTがタグを閉じないようにして、複雑なループロジックを使用できるようにする方法はありますか?または、単一のselectステートメントを使用せずにこのXMLを構築するという目標を達成できる別のOracle構造ですか?
私の最後の手段は、JavaやPerlなどの別の言語からXMLを生成することです。この言語では、データをフェッチして、そこで複雑な処理とXML生成を行うことができます。ただし、正しいXMLを文字列として返すSQL関数があればいいので、PL / SQLで実行できるのであれば、それが私の好みのルートです。