【发布时间】:2021-11-29 11:58:18
【问题描述】:
[LOG_Description] 列返回
OK Return value 1 RV1>Success<RV1Return value 2 RV2>test.user@domain.com<RV2
我想提取电子邮件地址。
执行
SUBSTRING(LOG_Description, CHARINDEX('RV2>',LOG_Description)+4, CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4)
返回一个Invalid length parameter passed to the LEFT or SUBSTRING function 错误。
我使用CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4检查了电子邮件地址本身的长度,等于24。
然后我用 24 替换了 SUBSTRING 函数的第三个参数,即 CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4,我确实得到了正确提取的电子邮件地址 test.user@domain.com.
当 CHARINDEX 函数在 SUBSTRING 之外执行时返回正确值时,我无法弄清楚为什么它使用直接值而不使用 SUBSTRING 中的 CHARINDEX 函数。
感谢任何帮助。
完整的初始查询如下:
SELECT LOG_Description,
-- SUBSTRING(LOG_Description, CHARINDEX('RV2>',LOG_Description)+4, 24),
SUBSTRING(LOG_Description, CHARINDEX('RV2>',LOG_Description)+4, CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4), -- this is the one that should work but throws the error
-- CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4
FROM
(SELECT LOG_Description
FROM dbo.WFLogs
WHERE LOG_WFDID = 2000
AND LOG_Description LIKE '%RV2>%'
) logEntry
根据建议将NULLIF() 与CHARINDEX() 一起使用,我将查询调整为:
SELECT LOG_Description,
-- SUBSTRING(LOG_Description, CHARINDEX('RV2>',LOG_Description)+4, 24),
SUBSTRING(LOG_Description, NULLIF(CHARINDEX('RV2>',LOG_Description)+4,0), NULLIF(CHARINDEX('<RV2',LOG_Description),0) - NULLIF(CHARINDEX('RV2>',LOG_Description)-4,0))
-- CHARINDEX('<RV2',LOG_Description) - CHARINDEX('RV2>',LOG_Description)-4
FROM
(SELECT LOG_Description
FROM dbo.WFLogs
WHERE LOG_WFDID = 2000
AND LOG_Description LIKE '%RV2>%'
) logEntry
原始查询与NULLIF()的区别在于后者不会抛出错误,也不会剥离最后一个<RV2标签:
test.user@domain.com<RV2
我尝试在查询结束时更改-4,但这并没有改变任何东西。 -2, -8 产生上述输出。
将其更改为正值,例如+4 再次抛出错误。
另一个建议是使用CORSS APPLY
select LOG_WFDID, LOG_TSInsert, LOG_Description, IsNull(Substring(LOG_Description, s+4, e - s-4),' ') EmailAddress
from dbo.WFLogs
cross apply (
values(NullIf(CharIndex('RV2>',LOG_Description),0), NullIf(CharIndex('<RV2',LOG_Description),0))
)x(s,e)
-- WHERE LOG_WFDID = 2000
-- AND LOG_TSInsert > DATEADD(DAY,-3,GetDate())
-- AND LOG_Description LIKE '%RV2>%'
ORDER BY LOG_TSInsert DESC
这种作品。它仍然会引发 Invalid length parameter passed to the LEFT or SUBSTRING function. 错误,但会返回包含电子邮件地址的列。但是,它也会返回其中没有标签的列(在不存在的记录之前没有发生在我身上)。
所以我尝试使用WHERE 来缩小结果范围,但WHERE 与CROSS APPLY 结合使用似乎不起作用。取消注释三个WHERE(上图)只会产生Invalid length parameter passed to the LEFT or SUBSTRING function. 错误。
【问题讨论】:
-
您的字符串操作适用于提供的值。它可能不适用于表中的其他数据,例如,如果您有一个缺少结束
Minimal, Reproducible Example -
我还删除了 mysql 标记 - 您已标记 tsql 并使用与 mysql 相矛盾的 charindex
-
So
select * from table where LOG_Description not like '%<RV2'和其他预期的标签都没有返回任何行? -
如果你使用
AND LOG_Description LIKE '%RV2>%<RV2'会怎样 -
您应该能够准确地复制我的值并能够重现问题。不是这样吗? - 是的,不是这样,your example works,这就是为什么你需要提供一个不起作用的例子 -
标签: sql tsql substring charindex