【问题标题】:Invalid argument for function integer IBM DB2函数整数 IBM DB2 的参数无效
【发布时间】:2018-06-19 21:48:52
【问题描述】:

我需要过滤掉表中 numer_lini 列中有数字并且介于 100 和 999 之间的行,当我注释掉我将 marsnr 转换为整数的行时,下面的代码工作得很好。但是,当我尝试使用它时,出现错误:在函数“INTEGER”的字符串参数中发现无效字符。当查看列表时,似乎只替换和翻译过滤器的数字就好了,选择只包含合法数字(唯一值列表不长,因此很容易用肉眼扫描)。那么为什么它无法投射东西呢?我也尝试使用整数(marsnr),但它会产生相同的错误。我需要强制转换,因为我需要数字范围,否则我会得到 7,80 等结果。正如我提到的,我使用的是 IBM DB2 数据库。

select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where numer_lini in (
    select marsnr
    from (
        select
        distinct numer_lini marsnr
        from alaska.trasa
        where case
        when replace(translate(numer_lini, '0','123456789','0'),'0','') = ''
        then numer_lini
        else 'no'
        end <> 'no'
    )
    where cast(marsnr as integer) between 100 and 999
)
fetch first 300 rows only 

【问题讨论】:

  • 我对db2不熟悉,但是7,80不是整数。我可以想象您需要指定如何转换真正的十进制值。
  • 不,不,我的意思是我得到的两个示例数字,它是两个整数 7 和 80。
  • 能否请您发布 DESCRIBE TABLE alaska.trasa
  • 如果numer_lini 中的任何一个是空字符串,就会发生这种情况。

标签: sql db2


【解决方案1】:

如果您查看 Db2 说明中的优化 SQL,您会看到 Db2 已将您的代码折叠成一个选择。

SELECT DISTINCT Q2.NUMER_LINI AS "NUMER_LINI",
   Q2.WAR_TRASY AS "WAR_TRASY",
   Q2.ID_PRZ1 AS "ID_PRZ1",
   Q2.ID_PRZ2 AS "ID_PRZ2",
   Q1.NUMER_LINI 
FROM ALASKA.TRASA AS Q1,
   ALASKA.TRASA AS Q2 
WHERE (Q2.NUMER_LINI = Q1.NUMER_LINI) 
AND (100 <= INTEGER(Q1.NUMER_LINI)) 
AND (INTEGER(Q1.NUMER_LINI) <= 999) 
AND (CASE WHEN (REPLACE(TRANSLATE(Q1.NUMER_LINI,
   '0',
   '123456789',
   '0'),
   '0',
   '') = '') THEN Q1.NUMER_LINI 
ELSE 'no' END <> 'no') 

使用 CASE 强制 Db2 首先执行“是整数”检查。此外,您不会检查空字符串。

例如有了这张表和数据

‪create‬‎ ‪TABLE‬‎ ‪alaska‬‎.‪trasa‬‎ ‪‬‎(‪numer_lini‬‎ ‪VARCHAR‬‎(‪10‬‎)‪‬‎,‪‬‎ ‪war_trasy‬‎ ‪INT‬‎ ‪‬‎,‪‬‎ ‪id_prz1‬‎ ‪INT‬‎,‪‬‎ ‪id_prz2‬‎ ‪INT‬‎)‪;
insert into alaska.trasa values ('',1,1,1),('99',1,1,1),('500',1,1,1),('3000',1,1,1),('00300',1,1,1),('AXS',1,1,1);

此 SQL 有效

select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when translate(numer_lini, '','0123456789') = ''
            and numer_lini <> ''
           then integer(numer_lini) else 0 end 
     between 100 and 999

尽管如果输入中有嵌入的空格,这确实会失败。例如。 '30 0'。为了迎合这一点,可能首选正则表达式。例如

select numer_lini, war_trasy, id_prz1, id_prz2
from alaska.trasa
where case when regexp_like(numer_lini, '^\s*[+-]?\s*((\d+\.?\d*)|(\d*\.?\d+))\s*$'))
           then integer(numer_lini) else 0 end 
     between 100 and 999

【讨论】:

  • 由于某种原因 regexp_like 对我不起作用并引发错误,但您的 translate 方法似乎运行良好,并且比我的更短且更合乎逻辑。谢谢;)
  • REGEXP 函数是 Db2 11.1 中的新功能,因此如果您是早期版本,则不会使用它们。 ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/…
猜你喜欢
  • 1970-01-01
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多