2010-01-14 3 views
3

Я хотел бы нарисовать VARCHAR на SQL INTEGER, предоставив значение по умолчанию, если какое-то значение в поле не будет правильно преобразовываться. Что-то вроде:Взаимозаменяемость строки для целого числа

sql> SELECT str FROM tbl; -- CREATE TABLE tbl (str VARCHAR(12), ...) 
    str 
======== 
    12345 
    -1 
    foo 

sql> SELECT CAST((CASE WHEN ... THEN str ELSE '-9999' END) AS INTEGER) AS "int" FROM tbl; 
    int 
======== 
    12345 
    -1 
    -9999 

Что я могу положить в эллипсис выше для получения желаемых результатов?

Этот вопрос задан и ответил на SO для многих конкретных БД, но мне интересно, есть ли более или менее портативный способ достичь этого?

+2

Нет никакого портативного способа сделать это. –

+0

Ваша лучшая ставка - хранить целочисленные данные в целых полях. Не смешивайте строковые и целочисленные данные вместе. – HLGEM

+0

@ HLGEM, вы правы, конечно, но это не та среда, которая у меня есть. – pilcrow

ответ

1

Учитывая, что диапазон значений acceptbale для INTEGER (32 бит? 64 бит?) Варьируется от реализации до реализации, для этого не существует конкретного способа, отличного от поставщика.

+0

+1, вы поднимаете превосходное внимание. Предположим, однако, что размер INT не является проблемой - скажем, я ограничен VARCHAR (3) и поэтому не будет переполнять какую-либо фактическую реализацию INTEGER. – pilcrow

1

Вот номинально портативный подход, используя простые, псевдо-POSIX regexen ANSI SQL-99 с оператором SIMILAR TO:

CAST ((CASE 
     WHEN string_column -- in perl: $string_column =~ /^\s*[+-]?\d+\s*$/ 
      SIMILAR TO 
      '[[:space:]]*([+-]|)[[:digit:]]+[[:space:]]*' 
     THEN 
     string_column 
     ELSE 
     '-9999'   -- default value for un-CASTable strings 
     END) 
     AS INTEGER 

Я говорю "номинально портативный", потому что SIMILAR TO не имеет широкой поддержки. (У PostgreSQL это было какое-то время, Firebird née Interbase обещает его в предстоящем выпуске 2.5, но об этом.)

Смежные вопросы