SQL语句中的Select列表是否可以使用正则表达式
我有一个SQL语句SQL语句中的Select列表是否可以使用正则表达式,sql,sql-server,Sql,Sql Server,我有一个SQL语句 select ColumnName from Table 我得到了这个结果 Error 192.168.1.67 UserName 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing .... 所以不管怎么说,这个领域有很多东西,我只想去掉“用户名” 我可以用正则表达式吗 我是说会是这样的 select SUBSTRING(ColumnName, 0, 5) from Table 但子字符串将被某种正则表达式替换。我对正则表
select ColumnName from Table
我得到了这个结果
Error 192.168.1.67 UserName 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing ....
所以不管怎么说,这个领域有很多东西,我只想去掉“用户名”
我可以用正则表达式吗
我是说会是这样的
select SUBSTRING(ColumnName, 0, 5) from Table
但子字符串将被某种正则表达式替换。我对正则表达式很满意,但我不知道如何在这种情况下应用它,或者即使你可以
如果我能让这一切正常工作,那就太好了,因为我计划将数据拉到一个临时表中,并做一些相当复杂的事情,将其与其他表进行匹配。如果我能让这一切正常工作,我就不用编写一个C应用程序了
谢谢。不,开箱即用,SQL Server不支持正则表达式
您可以通过部署到SQL Server中的SQL-CLR程序集对其进行改装。我认为您还是应该使用子字符串。使用正则表达式更灵活,但也会导致较大的处理开销。如果您必须处理大量的记录集,情况会变得更糟 你必须首先证明是否需要灵活性 如果是这样,您应该在此处阅读: 仅使用T-SQL可以如下所示:
SELECT 'Error 192.168.1.67 XUserNameX 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing' expr
INTO log_table
GO
WITH
split1 (expr, cstart, cend)
AS (
SELECT
expr, 1, 0
FROM
log_table a
), split2 (expr, cstart, cend, div)
AS (
SELECT
a.expr, a.cend + 1, CHARINDEX(' ', a.expr, a.cend + 1), 1
FROM
split1 a
UNION ALL
SELECT
a.expr, a.cend + 1, CHARINDEX(' ', a.expr, a.cend + 1), div+1
FROM
split2 a
WHERE
a.cend > 1
), substrings(expr, div)
AS (
SELECT
SUBSTRING(expr, cstart, cend - cstart), div
FROM
split2
)
SELECT expr from
substrings a
where
a.div = 3
更新
我们不知道这场战争从哪里开始
用户名是。除非我们能说“找到”
请在
第二空间'
这相当简单:
筛选出少于的字符串
两个空格或者有三个空格
或者更多的话;
找到第一个后的位置
空间或者,开始
第二个字;
找到第一个后的位置
第一个空格后的空格
或者,也可以从
第三个词;
确定第三条的长度
单词使用下一个单词的位置
空格或字符串的结尾是空的
只有三个字;
将上述值与
返回子字符串的函数
第三个字。
例如:
WITH MyTable (ColumnName)
AS
(
SELECT NULL
UNION ALL
SELECT ''
UNION ALL
SELECT 'One.'
UNION ALL
SELECT 'Two words.'
UNION ALL
SELECT 'Three word sentence.'
UNION ALL
SELECT 'Sentence containing four words.'
UNION ALL
SELECT 'Five words in this sentence.'
UNION ALL
SELECT 'Sentence containing more than five words.'
),
AtLeastThreeWords (ColumnName, pos_word_2_start)
AS
(
SELECT M1.ColumnName, CHARINDEX(' ', M1.ColumnName) + LEN(' ') + 1
FROM MyTable AS M1
WHERE LEN(M1.ColumnName) - LEN(REPLACE(M1.ColumnName, ' ', '')) >= 2
),
MyTable2 (ColumnName, pos_word_3_start)
AS
(
SELECT M1.ColumnName,
CHARINDEX(' ', M1.ColumnName, pos_word_2_start) + LEN(' ') + 1
FROM AtLeastThreeWords AS M1
),
MyTable3 (ColumnName, pos_word_3_start, pos_word_3_end)
AS
(
SELECT M1.ColumnName, M1.pos_word_3_start,
CHARINDEX(' ', M1.ColumnName, pos_word_3_start) + LEN(' ')
FROM MyTable2 AS M1
),
MyTable4 (ColumnName, pos_word_3_start, word_3_length)
AS
(
SELECT M1.ColumnName, M1.pos_word_3_start,
CASE
WHEN pos_word_3_start < pos_word_3_end
THEN pos_word_3_end - pos_word_3_start
ELSE LEN(M1.ColumnName) - pos_word_3_start + 1
END
FROM MyTable3 AS M1
)
SELECT M1.ColumnName,
SUBSTRING(M1.ColumnName, pos_word_3_start, word_3_length)
AS word_3
FROM MyTable4 AS M1;
…尽管您需要使其更加健壮,例如用户名值后没有尾随空格等。可能重复有用的阅读:我曾经也会给出大致相同的回答。然而,现在,我可以非常肯定地说——regex it。我不会为自己辩解太多。我只想说,T-SQL中的字符串操作工具还有很多需要改进的地方,C及其正则表达式的实现非常出色,而使用T-SQL,使用子字符串/charindex等,需要为您想要从字符串中提取的每一段数据编写单独的提取。使用正则表达式,一个模式就完成了。维护起来要简单得多。是的,可维护和慢节奏错误,混乱和快任何一天。IP地址可以是任何值。即上述IP地址192.168.1.89的长度为12个字符,10.5.4.3的长度仅为8个字符。此外,字段中将不包含字符串“Username”。它将只是一个实际的用户名“jerryb”或“georget”等。我的意思是,我们无法知道用户名的起始位置。除非我们说“在第二个空格后找到起始字符”。这有意义吗?
WITH MyTable (ColumnName)
AS
(
SELECT 'Error 192.168.1.67 UserName 0bce6c62-1efb-416d-bce5-71c3c8247b75 An existing ....'
UNION ALL
SELECT 'Username onedaywhen is invalid'
),
MyTable1 (ColumnName, pos1)
AS
(
SELECT M1.ColumnName, CHARINDEX('UserName ', M1.ColumnName) + LEN('UserName ') + 1
FROM MyTable AS M1
),
MyTable2 (ColumnName, pos1, pos2)
AS
(
SELECT M1.ColumnName, M1.pos1,
CHARINDEX(' ', M1.ColumnName, pos1) - M1.pos1
FROM MyTable1 AS M1
)
SELECT SUBSTRING(M1.ColumnName, M1.pos1, M1.pos2)
FROM MyTable2 AS M1;