DB2: Converting varchar to money

微笑、不失礼 提交于 2021-01-29 20:27:35

问题


I have 2 varchar(64) values that are decimals in this case (say COLUMN1 and COLUMN2, both varchars, both decimal numbers(money)). I need to create a where clause where I say this:

COLUMN1 < COLUMN2

I believe I have to convert these 2 varchar columns to a different data types to compare them like that, but I'm not sure how to go about that. I tried a straight forward CAST:

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

But I had to know that would be too easy. Any help is appreciated. Thanks!


回答1:


It really is that easy...this works fine...

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

You've got something besides a valid numerical character in your data.. And it's something besides leading or trailing whitespace...

Try the following...

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

That will show you the rows with alpha characters...

If the above does't return anything, then you've probably got a string with double decimal points or something... You could use a regex to find those.




回答2:


You can create a UDF like this to check which values can't be cast to 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

For example

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;

would return

C        
---------
£546     
12,456.88



回答3:


There is a built-in ability to do this without UDFs.
The xmlcast function below does "safe" casting between (var)char and decfloat (you may use as double or as decimal(X, Y) instead, if you want). It returns NULL if it's impossible to cast.
You may use such an expression twice in the WHERE clause.

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|                                          |


来源:https://stackoverflow.com/questions/59903353/db2-converting-varchar-to-money

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!