Използвайте xpath()
функция:
WITH x(col) AS (SELECT '<?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status></response>'::xml)
SELECT xpath('./status/text()', col) AS status
FROM x
/text() премахва околния <status>
Връща масив от xml - с един елемент в този случай:
status
xml[]
-------
{ERROR_MISSING_DATA}
Приложено към вашата маса
В отговор на актуализацията на вашия въпрос това може просто да бъде:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Ако сте сигурни, че има само един маркер за състояние на ред, можете просто да извлечете първия елемент от масива:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Ако може да има няколко елемента за състояние:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Получава ви 1-n реда на id .
Прехвърляне към xml
Тъй като сте дефинирали вашите колони да бъдат от тип text (вместо xml
, винатрябва за прехвърляне към xml изрично. Функцията xpath() очаква втория параметър от тип xml . Нетипизирана низова константа се принуждава към xml автоматично, но text колоната не е. Трябва изрично да прехвърлите.
Това работи без изрично прехвърляне:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
ACTE като в първия ми пример нужди тип за всяка колона в "общия табличен израз". Ако не бях преобразувал към определен тип, типът unknown биха били използвани - което не е същото като нетипизиран низ . Очевидно няма директно преобразуване, приложено между unknown и xml . Ще трябва да прехвърлите към text първо:unknown_type_col::text::xml . По-добре да прехвърляте към ::xml веднага.
Това беше затегнато с PostgreSQL 9.1 (мисля). По-старите версии бяха по-разрешителни.
Така или иначе, с всеки от тези методи низът трябва да бъде валиден xml или предаването (неявно или явно) ще предизвика изключение.