2015-11-04 2 views
1

Я хочу, чтобы выбрать столбец, который определяется как VARCHAR, как INTEGER, как это:избежать необходимости ошибки при преобразовании строки в Integer в DB2

SELECT ID, CAST(Col1 as INT) as MyOutput FROM MyTABLE 

Проблема заключается в том, если столбец имеет неверный формат (т.е. не может быть преобразован в Integer) Я хочу установить их в NULL. Есть ли способ сделать это в DB2?

+0

Но почему вы хотите использовать varchar как int? (Каждый раз, когда вы хотите сделать такой отбор, спросите себя, нужно ли обновлять проект таблицы.) – jarlh

+1

@jarlh Наиболее очевидной причиной является «потому что человек, пишущий этот запрос, может не иметь контроля над исходными данными». –

ответ

5

Один из способов сделать это, чтобы написать свою собственную функцию преобразования, которая обрабатывает исключения форматов, таких, как

create or replace function to_int_safe (str varchar(20)) 
returns int 
deterministic 
no external action contains sql 
begin 
    declare continue handler for sqlstate '22018' -- on conversion error 
    return null; 
    return cast(str as int); 
end 

затем использовать его в запросе:

SELECT ID, to_int_safe(Col1) as MyOutput FROM MyTABLE 
0

После сазе определяет, является ли строка содержит число, которое может быть отлито для целого. Кажется, это работает до сих пор. Тем не менее, это сложно и слишком долго. Я имею в виду, что он проверяет, может ли число преобразовываться в целое число, не говоря уже о том, как он будет искать десятичные числа.

select case when (-- no leading sign 
        (instr(value,'-') = 0 
       and instr(value,'+') = 0) 
        -- or one leading sign 
       or (left(ltrim(value),1) in ('-','+') 
       and instr(ltrim(value),'-',2) = 0 
       and instr(ltrim(value),'+',2) = 0)) 
       -- no spaces between digits 
      and instr(trim(translate(value,'','+-')),' ') = 0 
       -- only numbers and sign 
      and length(trim(translate(value,'','+-'))) = 0 
       -- no empty strings 
      and length(trim(value)) <> 0 
     then cast(value as int) 
     else cast(null as int) 
     end 

from table (
    select '1 ' value from sysibm.sysdummy1 
    union all 
    select '1.' value from sysibm.sysdummy1 
    union all 
    select 'a' value from sysibm.sysdummy1 
    union all 
    select '+1' value from sysibm.sysdummy1 
    union all 
    select ' -1' value from sysibm.sysdummy1 
    union all 
    select '- 1' value from sysibm.sysdummy1 
    union all 
    select '--1' value from sysibm.sysdummy1 
    union all 
    select '1 1' value from sysibm.sysdummy1 
    union all 
    select ''  value from sysibm.sysdummy1 
    union all 
    select ' ' value from sysibm.sysdummy1 
    union all 
    select cast(null as char) value from sysibm.sysdummy1 
) string_numbers; 

Его можно определить как функцию. Однако это не сделало бы его менее уродливым. Он может быть сокращен или содержать ошибки. Поэтому я предпочитаю mustaccio solution, хотя он должен иметь дело с обработкой исключений.