以下是我的Postgres表中的列响应。我想从Postgres数据库中的所有行中提取状态。状态可能有不同的大小,如SUCCESS
,所以我不想使用子字符串函数。有办法吗?
<?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>
所以我的表结构就像这样
Column | Type | Modifiers
-------------+-----------------------------+----------------------------------------------------------
id | bigint | not null default nextval('events_id_seq'::regclass)
hostname | text | not null
time | timestamp without time zone | not null
trn_type | text |
db_ret_code | text |
request | text |
response | text |
wait_time | text |
我想从每个请求中提取状态。我该怎么做?
下面是一个示例行。并假设表名为abc_events
id | 1870667
hostname | abcd.local
time | 2013-04-16 00:00:23.861
trn_type | A
request | <?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>
response | <?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>
答案 0 :(得分:15)
使用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;
每id
获取1行n。
xml
由于您已将列定义为text
类型(而不是xml
,因此您需要明确地转换为xml
。函数{{1期望xpath()
类型的第二个参数。无类型的字符串常量会自动强制转换为xml
,但 xml
列则不会。您需要强制转换明确。
这没有明确的演员:
text
CTE 就像在我的第一个例子中需要“公用表表达式”中每一列的类型。如果我没有转换为特定类型,则会使用类型 SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
- 不与无类型字符串相同。显然,unknown
和unknown
之间没有直接转换。您必须先转换为xml
:text
。最好立即投射到unknown_type_col::text::xml
。
PostgreSQL 9.1(我认为)已经收紧了。旧版本更宽松。
无论哪种方式,使用任何这些方法,字符串必须是有效的xml ,否则强制转换(隐式或显式)将引发异常。