Invalid length parameter passed to the RIGHT function in update statement

浪子不回头ぞ 提交于 2019-12-25 07:32:26

问题


does anybody know why my update is not working if I try to set two of the columns at the same time?

  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

If I run the query with updating just one column, then it works as it is expected to work. If I run with both, I get the following err:

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

I know that this can happen when CHARINDEX returns 0 but I am trying to control that with the WHERE clause.


回答1:


You have an OR in the WHERE clause. If you really want to control it, replace it with an 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

Alternatively:

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 '%#%';



回答2:


The reason for your error message is a negative value being passed to the RIGHT function. From BOL:

integer_expression Is a positive integer that specifies how many characters of character_expression will be returned. If integer_expression is negative, an error is returned.

Your WHERE condition contains an OR, which will allow rows without a "#" to be included where the "other" column does contain one.

Try amending your OR to an 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:


If you want to update both and sometimes one or the other will have the "#" then you can use:

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

Of course, alternatively you could break it down into two UPDATE statements, but I think that this one will run faster since it will only have to make one pass through the table.




回答4:


Maybe something like:

    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


来源:https://stackoverflow.com/questions/37616694/invalid-length-parameter-passed-to-the-right-function-in-update-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!