sql >> Databáze >  >> RDS >> PostgreSQL

Extrahování hodnoty xml tagu v PostgreSQL

Použijte xpath() funkce:

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() odstraní okolní <status> tag.
Vrátí pole xml - v tomto případě s jediným prvkem:

status
xml[]
-------
{ERROR_MISSING_DATA}

Použito na váš stůl

V reakci na aktualizaci vaší otázky to může být:

SELECT id, xpath('./status/text()', response::xml) AS status
FROM   tbl;

Pokud jste si jisti, že na řádek je pouze jedna stavová značka, můžete jednoduše extrahovat první položku z pole:

SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM   tbl;

Pokud může existovat více položek stavu:

SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM   tbl;

Získáte 1-n řádků na id .

Odesílat do xml

Protože jste definovali sloupce typu text (místo xml , potřebujete přenést do xml výslovně. Funkce xpath() očekává 2. parametry typu xml . Netypová řetězcová konstanta je vynucena na xml automaticky, ale text sloupec není. Musíte odesílat explicitně.

Toto funguje bez explicitního obsazení:

  SELECT xpath('./status/text()'
      ,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')

CTE jako v mém prvním příkladu potřeby typ pro každý sloupec v "společném tabulkovém výrazu". Pokud bych nepřetypoval na konkrétní typ, typ unknown by bylo použito – což není totéž jako nezadaný řetězec . Je zřejmé, že mezi unknown není implementována žádná přímá konverze a xml . Museli byste přenášet do text první:unknown_type_col::text::xml . Je lepší přenést do ::xml hned.

Toto bylo zpřísněno s PostgreSQL 9.1 (myslím). Starší verze byly tolerantnější.

Ať tak či onak, u kterékoli z těchto metod musí být řetězec platný xml nebo obsazení (implicitní nebo explicitní) vyvolá výjimku.




  1. TSQL DateDiff vrátí počet dní se 2 desetinnými místy

  2. dotaz mySQL získat TOP 100 skóre mě šílí

  3. Vždy zobrazovat desetinná místa v SQL?

  4. Nelze vyřešit konflikt řazení mezi SQL_Latin1_General_CP1_CI_AS a Latin1_General_CI_AS v operaci rovná se