DB2: конвертация varchar в деньги - PullRequest
0 голосов
/ 24 января 2020

У меня есть 2 значения varchar (64), которые в данном случае являются десятичными (скажем, COLUMN1 и COLUMN2, оба varchars, оба десятичные числа (деньги)). Мне нужно создать предложение where, где я говорю это:

COLUMN1 < COLUMN2

Я считаю, что мне нужно преобразовать эти 2 столбца varchar в разные типы данных, чтобы сравнить их, но я не уверен, как go об этом. Я попробовал прямо CAST:

CAST(COLUMN1 AS DECIMAL(9,2)) < CAST(COLUMN2 AS DECIMAL(9,2))

Но я должен был знать, что это будет слишком легко. Любая помощь приветствуется. Спасибо!

Ответы [ 3 ]

2 голосов
/ 25 января 2020

Вы можете создать подобную UDF, чтобы проверить, какие значения не могут быть приведены к DECIMAL

CREATE OR REPLACE FUNCTION IS_DECIMAL(i VARCHAR(64)) RETURNS INTEGER
    CONTAINS SQL
    --ALLOW PARALLEL -- can use this on Db2 11.5 or above
    NO EXTERNAL ACTION
    DETERMINISTIC
BEGIN 
  DECLARE NOT_VALID CONDITION FOR SQLSTATE '22018';
  DECLARE EXIT HANDLER FOR NOT_VALID RETURN 0;

  RETURN CASE WHEN CAST(i AS DECIMAL(31,8)) IS NOT NULL THEN 1 END;
END

Например,

CREATE TABLE S ( C VARCHAR(32) );
INSERT INTO S VALUES ( '  123.45 '),('-00.12'),('£546'),('12,456.88');
SELECT C FROM S WHERE IS_DECIMAL(c) = 0;

вернет

C        
---------
£546     
12,456.88
1 голос
/ 25 января 2020

Это действительно так просто ... это прекрасно работает ...

select cast('10.15' as decimal(9,2)) - 1
from sysibm.sysdummy1;

В ваших данных есть что-то кроме действительного числового символа ... И это что-то помимо начального или конечного пробела. ..

Попробуйте следующее ...

select *
from table 
where translate(column1, '           ','0123456789.')
      <> ' '
     or translate(column2, '           ','0123456789.')
      <> ' '

Это покажет вам строки с альфа-символами ...

Если приведенное выше ничего не возвращает, тогда вы, вероятно, получили строку с двойными десятичными точками или что-то в этом роде ... Вы можете использовать регулярное выражение, чтобы найти их.

0 голосов
/ 25 января 2020

Существует встроенная возможность сделать это без UDF.
Функция xmlcast, приведенная ниже, выполняет «безопасное» приведение между (var)char и decfloat (вы можете использовать as double или как decimal(X, Y) вместо этого, если хотите). Возвращает NULL, если невозможно выполнить приведение.
Вы можете использовать такое выражение дважды в предложении WHERE.

SELECT 
  S
, xmlcast(xmlquery('if ($v castable as xs:decimal) then xs:decimal($v) else ()' passing S as "v") as decfloat) D 
FROM (VALUES ( '  123.45 '),('-00.12'),('£546'),('12,456.88')) T (S);

|S        |D                                         |
|---------|------------------------------------------|
|  123.45 |123.45                                    |
|-00.12   |-0.12                                     |
|£546     |                                          |
|12,456.88|                                          |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...