我有这样的字段:
for (int b : a) {
,我正在尝试从左侧的第一个p = p + b;
之后提取文本。这将是一个或两个数字/字母。另外,同时我想先从左边看UPDATE</transactionType><column><name>prio</name><newValue>5</newValue><oldValue>1</oldValue><newValue>aaa<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>
UPDATE</transactionType><column><name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>
。结果是:
<newValue>
答案 0 :(得分:1)
由于它是不完整的XML,因此我们使用简单的字符串函数。
LOCATE可以找到子字符串的位置。
LEFT从头到位置获取一个子字符串。
从该子字符串中,SUBSTRING_INDEX函数很容易在最终标签之后获取字符。
示例代码:
-- test table
drop table if exists YourTable;
create table YourTable (col varchar(1000));
-- Sample data
insert into YourTable (col) values
('UPDATE</transactionType><column><name>prio</name><newValue>5</newValue><oldValue>1</oldValue><newValue>aaa<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>'),
('UPDATE</transactionType><column> <name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>');
-- Query
SELECT
SUBSTRING_INDEX(LEFT(col, LOCATE('</oldValue>', col)-1),'>',-1) AS oldValue,
SUBSTRING_INDEX(LEFT(col, LOCATE('</newValue>', col)-1),'>',-1) AS newValue
FROM YourTable;
结果:
oldValue newValue
1 5
11 51
对妊娠here
的测试旁注:
在MySql 8中,您也可以为此使用REGEXP_SUBSTR。
SELECT
REGEXP_SUBSTR(col,'(?<=<oldValue>)[^<>]*(?=</oldValue)',1,1) as oldValue,
REGEXP_SUBSTR(col,'(?<=<newValue>)[^<>]*(?=</newValue>)',1,1) as newValue
FROM YourTable;
对 db <>小提琴here
的测试 (但请保持沉默。有些人会因为使用正则表达式来解析XML而对您不满意。例如here。
但是再说一次,无效的XML实际上不是XML)
答案 1 :(得分:0)
正如我所理解的那样,您仅粘贴了xml字段的一部分。如果它是有效的xml,则可以通过函数ExtractValue
我将为您提供一个简单的示例:
数据定义
create table Test(id integer, title varchar(2000));
insert into Test(id, title) values(1, "<a><b>X</b><b>Y</b></a>");
查询
select ExtractValue(title, '/a/b[1]') from Test;
此查询返回标签a内的第一个元素b(请注意查询中的“ 1”。在这种情况下,结果为X
。
因此,在您的情况下,您可以在单个查询中使用两个ExtractValue函数来选择第一个newValue标记和第一个oldValue标记。
答案 2 :(得分:0)
由于它不是正确的XML,让我们尝试一些底层字符串工具。
mysql> SELECT SUBSTRING_INDEX(
SUBSTRING_INDEX(
'UPDATE</transactionType><column><name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>',
'</newValue>', 1),
'<newValue>', -1) AS x;
+----+
| x |
+----+
| 51 |
+----+
1 row in set (0.00 sec)
说明:
</newValue>
获取子字符串。<newValue>
之后获取文本尝试其他字符串。
这对于至少十年前的任何MySQL版本都适用。
<oldvalue>
应该以相同的方式工作,并且可以成为SELECT
中的第二个“列”。
答案 3 :(得分:0)
SUBSTRING_INDEX
函数在某些情况下很有用。对于包含指定标签的“格式正确”的值,我们可以获得可用的结果。但是当值的格式不正确时,这种方法就会瓦解(返回潜在的意外结果)。
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( t.foo ,'</oldValue>',1),'<oldValue>',-1) AS first_oldValue
, SUBSTRING_INDEX(SUBSTRING_INDEX( t.foo ,'</newValue>',1),'<newValue>',-1) AS first_newValue
FROM ( SELECT 'UPDATE</transactionType><column><name>prio</name><newValue>5</newValue><oldValue>1</oldValue><newValue>aaa<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>' AS foo
UNION ALL
SELECT 'UPDATE</transactionType><column><name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>'
) t
WHERE t.foo LIKE '%<oldValue>%</oldValue>%'
AND t.foo LIKE '%<newValue>%</newValue>%'
我们可以将完整性检查合并到SELECT列表中的表达式中
SELECT CASE WHEN t.foo LIKE '%<oldValue>%</oldValue>%' THEN
SUBSTRING_INDEX(SUBSTRING_INDEX( t.foo ,'</oldValue>',1),'<oldValue>',-1)
END AS first_oldValue
, CASE WHEN t.foo LIKE '%<newValue>%</newValue>%' THEN
SUBSTRING_INDEX(SUBSTRING_INDEX( t.foo ,'</newValue>',1),'<newValue>',-1)
END AS first_newValue
FROM ( SELECT 'UPDATE</transactionType><column><name>prio</name><newValue>5</newValue><oldValue>1</oldValue><newValue>aaa<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>' AS foo
UNION ALL
SELECT 'UPDATE</transactionType><column><name>prio</name><newValue>51</newValue><oldValue>11</oldValue><newValue>bbb<oldValue>10863321</oldValue></column></row></table></businessObjectChanges>'
) t