【问题标题】:Invalid length parameter passed to the RIGHT function in update statement在更新语句中传递给 RIGHT 函数的长度参数无效
【发布时间】:2016-06-03 14:13:33
【问题描述】:

如果我尝试同时设置两列,有人知道为什么我的更新不起作用吗?

  UPDATE mytable
    SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
        [Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
    WHERE CHARINDEX('#', [Customer]) > 0 OR
              CHARINDEX('#', [Segment]) > 0

如果我只更新一列来运行查询,那么它会按预期工作。如果我同时运行两者,我会得到以下错误:

Invalid length parameter passed to the RIGHT function. The statement has been terminated.

我知道当 CHARINDEX 返回 0 时会发生这种情况,但我正在尝试使用 WHERE 子句来控制它。

【问题讨论】:

    标签: sql sql-server charindex


    【解决方案1】:

    您在WHERE 子句中有一个OR。如果你真的想控制它,把它换成AND

    UPDATE mytable
        SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
            [Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
        WHERE CHARINDEX('#', [Customer]) > 0 AND
              CHARINDEX('#', [Segment]) > 0
    

    或者:

    UPDATE mytable
        SET [Customer] = (CASE WHEN Customer LIKE '%#%'
                               THEN RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1)
                               ELSE Customer
                          END)
            [Segment] = (CASE WHEN Segment LIKE '%#%'
                              THEN RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
                              ELSE Segment
                         END)
        WHERE Customer LIKE '%#%' OR Segment LIKE '%#%';
    

    【讨论】:

    • 嗨戈登,很抱歉我没有提到它,但我尝试了相同的结果..然后查询运行但它总是影响 0 行..但我知道它应该影响所有行,因为当我单独运行它时,它会影响所有行
    • 好的,我相信现在是空数据的情况。我没有注意到表中还没有导入一些数据。谢谢!
    【解决方案2】:

    您的错误消息的原因是传递给RIGHT 函数的负值。来自BOL

    整数表达式 是一个正整数,指定将返回多少个 character_expression 字符。如果 integer_expression 为负数,则返回错误。

    您的WHERE 条件包含OR,这将允许在“其他”列包含一个时包含没有“#”的行。

    尝试将您的OR 修改为AND

    UPDATE mytable
        SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
            [Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
        WHERE CHARINDEX('#', [Customer]) > 0 AND
                  CHARINDEX('#', [Segment]) > 0
    

    【讨论】:

    • 感谢您的解释!
    【解决方案3】:

    如果您想同时更新两者并且有时其中一个或另一个将带有“#”,那么您可以使用:

    UPDATE MyTable
    SET
        Customer = CASE
                       WHEN CHARINDEX('#', Customer) > 0 THEN RIGHT(Customer, CHARINDEX('#', REVERSE(Customer)) -1)
                       ELSE Customer
                   END,
        Segment = CASE
                       WHEN CHARINDEX('#', Segment) > 0 THEN RIGHT(Segment, CHARINDEX('#', REVERSE(Segment)) -1)
                       ELSE Segment
                   END
    WHERE
        CHARINDEX('#', Customer) > 0 OR
        CHARINDEX('#', Segment) > 0
    

    当然,您也可以将其分解为两个UPDATE 语句,但我认为这个会运行得更快,因为它只需要通过表格。

    【讨论】:

      【解决方案4】:

      可能是这样的:

          UPDATE mytable SET 
          [Customer] = Case When CHARINDEX('#', [Customer]) > 0 Then RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) Else [Customer] End ,
          [Segment] = Case When CHARINDEX('#', [Segment]) > 0 Then RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1) Else [Segment] End
          WHERE
          CHARINDEX('#', [Customer]) > 0 OR
          CHARINDEX('#', [Segment]) > 0
      

      【讨论】:

      • 也许这实际上是最好的解决方案。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多