如何从SQL Server中的单行中提取多个字符串
例如,我有下表数据:如何从SQL Server中的单行中提取多个字符串,sql,sql-server,pattern-matching,Sql,Sql Server,Pattern Matching,例如,我有下表数据: id | text -------------------------------------------------------------------------------- 1 | Peter (Peter@peter.de) and Marta (marty@gmail.com) are doing fine. 2 | Nothing special here 3 | Another email address (me@m
id | text
--------------------------------------------------------------------------------
1 | Peter (Peter@peter.de) and Marta (marty@gmail.com) are doing fine.
2 | Nothing special here
3 | Another email address (me@my.com)
现在我需要一个select,它返回文本列中的所有电子邮件地址,只需检查括号即可,如果文本列中有多个地址,它将返回多行。我知道,但是我完全不知道如何找到第二个和更多的结果。子字符串函数有起始位置参数。因此,您可以找到第一个引用,并在引用位置+引用长度处开始循环中的下一次搜索。您需要编写一个函数,以分隔字符串或表的形式返回值。使用@-符号进入电子邮件地址,然后前后扫描,直到出现空白或电子邮件地址中无效的字符、开始位置或开始或最后一个字符。您可以使用cte递归删除字符串
declare @T table (id int, [text] nvarchar(max))
insert into @T values (1, 'Peter (Peter@peter.de) and Marta (marty@gmail.com) are doing fine.')
insert into @T values (2, 'Nothing special here')
insert into @T values (3, 'Another email address (me@my.com)')
;with cte([text], email)
as
(
select
right([text], len([text]) - charindex(')', [text], 0)),
substring([text], charindex('(', [text], 0) + 1, charindex(')', [text], 0) - charindex('(', [text], 0) - 1)
from @T
where charindex('(', [text], 0) > 0
union all
select
right([text], len([text]) - charindex(')', [text], 0)),
substring([text], charindex('(', [text], 0) + 1, charindex(')', [text], 0) - charindex('(', [text], 0) - 1)
from cte
where charindex('(', [text], 0) > 0
)
select email
from cte
结果
email
Peter@peter.de
me@my.com
marty@gmail.com
这假设没有恶意括号,如果文本可以包含任何XML实体字符,则需要在中添加一些额外的替换
WITH basedata(id, [text])
AS (SELECT 1, 'Peter (Peter@peter.de) and Marta (marty@gmail.com) are doing fine.'
UNION ALL
SELECT 2, 'Nothing special here'
UNION ALL
SELECT 3, 'Another email address (me@my.com)'),
cte(id, t, x)
AS (SELECT *,
CAST('<foo>' + REPLACE(REPLACE([text],'(','<bar>'),')','</bar>') + '</foo>' AS XML)
FROM basedata)
SELECT id,
a.value('.', 'nvarchar(max)') as address
FROM cte
CROSS APPLY x.nodes('//foo/bar') as addresses(a)
我们能假设数据中绝对没有不平衡的括号吗?是的。我可以在以后解决这些错误,但这里需要一个工作示例。在我的现实世界问题中根本不是电子邮件地址,这只是为了说明问题并创建一个小例子。@Daniel。你需要写一个UDF。每次我必须接近一个SQL Server,5分钟后我开始讨厌它。。。但没关系。我可以在只有只读访问权限的数据库中编写UDF吗?喜欢在临时桌子空间?你能举例说明如何编写一个UDF,从一个输入行返回零到多行吗?不是我的下一票。。。但我相信,因为您的答案似乎没有在SQL中执行。@Daniel:返回许多值,请阅读SQL Server联机丛书中返回表类型的函数。如果你没有必要的对象创建特权,那么你就不能这样做。@Martin,如果这是你的否决票,那么你愿意解释一下原因吗?