【问题标题】:SQL Server 2008 Standard - Invalid length parameter passed to the LEFT or SUBSTRING functionSQL Server 2008 Standard - 传递给 LEFT 或 SUBSTRING 函数的长度参数无效
【发布时间】:2017-12-01 22:57:06
【问题描述】:

有很多同名的问题,但我认为我的情况比表面上看到的要多。

这是我的查询:

SELECT  SALH.COMPANY,
        SALI.MATERIAL,
        SALH.NAME1,
        SALH.DEPARTMENT,
        SALH.DOCTYPE,
        SALH.DOCNUM,
        SALI.MATERIAL,
        SALI.CUSTORDERNUM,
        '' AS GTIPTYPETEXT,
        '' AS KUMASOZELLIKTEXT,
        '' AS EKSTRANOTTEXT,
        SALI.PRODDATE AS REVIZEDATE,
        SUM(SALI.QUANTITY) AS QUANTITY,
        '' AS LTEXT,
        SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5) AS OPTKEY,
        '' AS RENK,
        SALI.SPRICE,
        SALI.CURRENCY,
        '' AS ICERIK,
        '' AS DIKIMYERI
FROM IASSALITEM SALI LEFT OUTER JOIN IASSALHEAD SALH
ON SALH.CLIENT = SALI.CLIENT
    AND SALH.COMPANY = SALI.COMPANY
    AND SALH.DOCTYPE = SALI.DOCTYPE
    AND SALH.DOCNUM = SALI.DOCNUM
WHERE SALH.CLIENT = '00'
        AND SALH.COMPANY = '01'
        AND SALI.PLANT = '01'
        AND SALH.DOCNUM LIKE '%'
        AND SALH.DOCTYPE IN ('SD', 'SC', 'ND', 'NC')
        AND SALH.ORDSTAT <> 2
        AND SALI.ORDSTAT <> (0 * 3 - 1)
        AND SALH.ISSTOP = 0
        AND SALH.ISDELETE = 0
        AND SALI.PRODDATE >= '2017-06-26'
        AND SALI.PRODDATE < '2017-07-02'
        AND SALH.CUSTOMER LIKE '%'
        AND SALH.NAME1 LIKE '%'
        AND SALH.DEPARTMENT LIKE '%'
GROUP BY    SALH.COMPANY,
        SALH.NAME1,
        SALH.DEPARTMENT,
        SALH.DOCTYPE,
        SALH.DOCNUM,
        SALI.MATERIAL,
        SALI.SHIPCOUNTRY,
        SALI.CUSTORDERNUM,
        SALI.PRODDATE,
        SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5),
        SALI.SPRICE,
        SALI.CURRENCY
ORDER BY SALI.PRODDATE

这给了我“传递给 LEFT 或 SUBSTRING 函数的长度参数无效”。错误。


信息:VOPTIONS 值与此类似:#0110##02120#

这是我尝试过的:

  1. 认为有一个有问题的 VOPTIONS 没有在正确的位置包含“#02”部分或根本没有,我从 SELECT 和 GROUP BY 中注释掉了 SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5) 和在 WHERE 子句中添加了 AND PATINDEX('%#02%', SALI.VOPTIONS) &lt; 5 以查找返回小于 5 的 PATINDEX 值导致负值的 VOPTIONS。 这应该至少返回一条 VOPTIONS 损坏的记录,但它没有返回任何内容。

  2. 我尝试选择给定 where 子句中的所有 VOPTIONS 并一一检查。他们都检查得很好。

  3. 更有趣的是,如果我在这一行中将&lt; 更改为&lt;= -> AND SALI.PRODDATE &lt; '2017-07-02' 查询有效。扩大日期范围会使错误消失,这对我来说没有任何意义。

谁能看到我在这里遗漏了什么?

编辑:标签分隔的数据(只是更改了客户名称):https://pastebin.com/kE8ViWu4

【问题讨论】:

  • 你想从那个子字符串中得到什么?我们需要大量的数据样本。
  • 是否存在 VOPTIONS 为 NULL 的行?表中的任何一个,无论它们是否适合 WHERE 子句。
  • @TabAlleman 。 . . NULL 值将简单地返回 NULL。
  • 不,它确实返回了一个错误,但另一个错误:SELECT SUBSTRING(NULL, 4, PATINDEX('%#02%', NULL) - 5) 返回“参数数据类型 NULL 对 patindex 函数的参数 2 无效。”
  • 没关系,当我使用一个变量来保存 NULL 时,它确实返回 NULL,所以 Gordon 是正确的。

标签: sql sql-server sql-server-2008 substring patindex


【解决方案1】:

问题出现的明显地方是这个表达式:

SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5) AS OPTKEY,

如果'#02' 从未出现在SALI.VOPTIONS 中,那么您将收到此错误。解决此问题的一种方法是使用CASE 语句:

(CASE WHEN SALEI.VOPTIONS LIKE '_____%#02%'
      THEN SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5)
 END) AS OPTKEY,

【讨论】:

  • @VolkanSen 有 4 个下划线呢? '____%#02%'
  • @VolkanSen 。 . .您还需要在 GROUP BY 中使用相同的表达式。
【解决方案2】:

我的猜测是你有一个在 patindex 子句中返回 null 或否定结果的值。

我如何看待这样的问题是我试图找到导致问题的数据,所以我会运行这个查询来查看问题是什么:

SELECT  SALH.COMPANY,
        SALI.MATERIAL,
        SALH.NAME1,
        SALH.DEPARTMENT,
        SALH.DOCTYPE,
        SALH.DOCNUM,
        SALI.MATERIAL,
        SALI.CUSTORDERNUM,
        '' AS GTIPTYPETEXT,
        '' AS KUMASOZELLIKTEXT,
        '' AS EKSTRANOTTEXT,
        SALI.PRODDATE AS REVIZEDATE,
        SUM(SALI.QUANTITY) AS QUANTITY,
        '' AS LTEXT,
        SALI.VOPTIONS,
        PATINDEX('%#02%', SALI.VOPTIONS),
        len(SALI.VOPTIONS)
        'SUBSTRING(SALI.VOPTIONS, 4, ' +cast(PATINDEX('%#02%', SALI.VOPTIONS) - 5 as varchar(50))+ ')' AS OPTKEY,
        '' AS RENK,
        SALI.SPRICE,
        SALI.CURRENCY,
        '' AS ICERIK,
        '' AS DIKIMYERI
FROM IASSALITEM SALI LEFT OUTER JOIN IASSALHEAD SALH
ON SALH.CLIENT = SALI.CLIENT
    AND SALH.COMPANY = SALI.COMPANY
    AND SALH.DOCTYPE = SALI.DOCTYPE
    AND SALH.DOCNUM = SALI.DOCNUM
WHERE SALH.CLIENT = '00'
        AND SALH.COMPANY = '01'
        AND SALI.PLANT = '01'
        AND SALH.DOCNUM LIKE '%'
        AND SALH.DOCTYPE IN ('SD', 'SC', 'ND', 'NC')
        AND SALH.ORDSTAT <> 2
        AND SALI.ORDSTAT <> (0 * 3 - 1)
        AND SALH.ISSTOP = 0
        AND SALH.ISDELETE = 0
        AND SALI.PRODDATE >= '2017-06-26'
        AND SALI.PRODDATE < '2017-07-02'
        AND SALH.CUSTOMER LIKE '%'
        AND SALH.NAME1 LIKE '%'
        AND SALH.DEPARTMENT LIKE '%'
GROUP BY    SALH.COMPANY,
        SALH.NAME1,
        SALH.DEPARTMENT,
        SALH.DOCTYPE,
        SALH.DOCNUM,
        SALI.MATERIAL,
        SALI.SHIPCOUNTRY,
        SALI.CUSTORDERNUM,
        SALI.PRODDATE,
        --SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5),
        SALI.SPRICE,
        SALI.CURRENCY
ORDER BY SALI.PRODDATE

然后仔细检查您的查询结果并手动找出整个子字符串中的值。一旦您知道您遇到的数据问题,解决方案通常是显而易见的。我的编辑将为您提供发送到子字符串的值是什么以及字段的长度,如果有些不是 4 个字符的长度,这将是一个问题。

【讨论】:

  • 是的,我这样做了。我试图找到会为此表达式返回小于 5 的值的 VOPTIONS:PATINDEX('%#02%', SALI.VOPTIONS)。没有记录……然后我手动一一检查了所有的VOPTIONS,但没有发现任何异常。
  • 那么它可能是子字符串本身。我愿意尝试一下
【解决方案3】:

使用它来识别导致错误的行...

select * 
from IASSALITEM 
where (PATINDEX('%#02%', VOPTIONS) - 5) < 0

或者内联的情况下...

case 
when (PATINDEX('%#02%', SALI.VOPTIONS) - 5) >= 0
then  SUBSTRING(SALI.VOPTIONS, 4, PATINDEX('%#02%', SALI.VOPTIONS) - 5) 
end AS OPTKEY,
...
...
where SALI.VOPTIONS is not null

【讨论】:

  • 第一个查询不返回任何记录。将该案例添加到原始查询中仍然会产生错误
  • 您在 VOPTIONS 中没有任何空值?它必须是这两种情况之一@VolkanSen 尝试使用 null where 子句进行编辑。如果这不起作用,请使用 pastebin.com 粘贴所有 VOPTIONS
  • 整个表中也没有NULL值。
  • 添加到原帖@scsimon
  • @VolkanSen 基于该数据,不会抛出错误,因此查询中的其他地方可能存在另一个问题,可能高于或低于此。见这里:rextester.com/BFWRV69171
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多