SQL charindex throw由于周期而传递给LEFT或SUBSTRING函数的无效长度参数?

时间:2012-03-30 16:24:23

标签: sql tsql

我的查询的where子句中有以下行,但我不断收到此错误:

Msg 537, Level 16, State 3, Line 3
Invalid length parameter passed to the LEFT or SUBSTRING function.

    SUBSTRING(
        [email], 
        1, 
        CHARINDEX('@',[email])-1
    ) =
    SUBSTRING(
        [email], 
        CHARINDEX('@',[email])+1,
        CHARINDEX('.', [email])
    )

错误源自CHARINDEX('.', [email])

如果我将句号更改为字母,我不会收到错误。每个记录都有一个句点,即使没有记录,charindex函数也会返回0,这不会导致抛出此错误。我一定很遗憾。请帮忙!

EDIT。

我试过把它扔进一个isnull isnull(CHARINDEX('.', [email]), 1)里面,以防因为某些原因它返回null,但这也不起作用。

3 个答案:

答案 0 :(得分:22)

错误源于

CHARINDEX('@',[email])-1

如果数据中没有@符号,则charindex返回0.从中减去1得到-1,这在子字符串函数中无效。

试试这个。

CHARINDEX('@',[email] + '@')-1

这会强制匹配,确保CharIndex将始终返回值> = 1,这将导致子字符串函数成功。

答案 1 :(得分:0)

我不确定这是你唯一的问题。我猜您正在尝试查看电子邮件地址的第一部分,并将其与域的第一部分进行比较。例如,如果电子邮件地址是“name@company.com”,那么您正在寻找“名称”和“公司”。子串不占用2个位置,它占据位置和长度。因此,要获得“公司”,您需要这样做:

SUBSTRING(
    [email],
    CHARINDEX('@', [email]) + 1,
    CHARINDEX('.', [email]) - CHARINDEX('@', [email]) - 1
)

+1和-1是为了说明CHARINDEX会给你“@”的位置,所以它会在结果中包含“@”。

不幸的是,这并不总是有效,因为如果你有一个像“first.last@company.com”这样的地址,那么第一个“。”的位置。将小于“@”的位置,从而产生负数。

因此您需要这样做:

SUBSTRING(
    [email],
    CHARINDEX('@', [email]) + 1,
    CHARINDEX('.', [email], CHARINDEX('@', [email])) - CHARINDEX('@', [email]) - 1
)

这样可以确保您正在寻找第一个“。”之后 ”@”。但是,如果你没有“@”但是你确实有一个“。”,这仍然不起作用。 (例如“invalidemail.companay.com”)。因此,您可以通过上面的解决方案在末尾添加“@”,但更好的方法是:

SUBSTRING(
    [email],
    CHARINDEX('@', [email]) + 1,
    CASE WHEN 
        CHARINDEX('.', [email], CHARINDEX('@', [email])) - CHARINDEX('@', [email]) - 1 < 0 
    THEN 0 
    ELSE 
        CHARINDEX('.', [email], CHARINDEX('@', [email])) - CHARINDEX('@', [email]) - 1
    END
)

答案 2 :(得分:0)

您可以在行末添加“”,并显示类似错误

SUBSTRING(
    [email], 
    1, 
    CHARINDEX('@',[email]+' ')-1
) =
SUBSTRING(
    [email], 
    CHARINDEX('@',[email])+1,
    CHARINDEX('.', [email])
)