В SQL, мне нужно создать XML-код, который выглядит следующим образом:Как я могу вызвать функцию db2 и вернуть ей несколько данных записи 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
Но теперь, когда я вызываю функцию со значениями (xml_entity_phones (256285)) ;, я получаю ++ ++++++++++++. И когда я вызываю процедуру, которая вызывает эту функцию, я получаю эту ошибку:
SQL State: 22023 Vendor Код: -802 Сообщение: [SQL0802] преобразования данных или данных об ошибке отображения. Причина. , , , , : Возникла ошибка типа 10. 10 - Пользовательская функция вернула ошибку сопоставления.
Я заметил, что когда я включаю дополнительный элемент телефонов, использующий xmlagg, как предлагается в нескольких ответах ниже, он возвращает результат xmlagg(). Однако у меня не может быть этого дополнительного элемента телефонов, потому что он противоречит стандарту, которому я должен придерживаться.
Есть ли способ вернуть xmlagg без дополнительного слоя?
Это то, на что я надеялся, но стандарт, заданный вызывающей процедурой (который действительно создает большой XML-документ, который включает телефоны, которые Я надеялся построить с этой функцией) не позволяет мне использовать родителя, такого как «Телефоны». Он должен быть в таком формате: – user2414410
Вы можете просто опустить внешний XMLELEMENT(), чтобы получить фрагмент XML, содержащий последовательность элементов телефона, хотя это не будет действительным XML-документом. – mustaccio
Я отредактирую свой исходный вопрос с требуемым форматом, но есть ли способ объединить несколько строк в один оператор xml внутри функции? – user2414410