Search code examples
sqlinformix

Data type casting inside a CASE statement


I am using Informix and have a CASE statement in a query as below:

CASE 
 when l.src_country = 'USA' then tl.cat--prodUSA.description
 when l.src_country = 'CAN' AND tl.fuel_type > 0 then tl.fuel_type
 when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat in ("DEF","DEFD") then 4194304
 when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat not in ("DEF","DEFD") then tl.fuel_type
 else 0
 END as product_code

In the above statement, "tl.cat" is of CHAR type & "tl.fuel_type" is of the type INT.

I need to do something like this:

CASE 
 when l.src_country = 'USA' then tl.cat--prodUSA.description
 when l.src_country = 'CAN' AND tl.fuel_type > 0 then tl.fuel_type :: CHARACTER
 when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat in ("DEF","DEFD") then 4194304
 when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat not in ("DEF","DEFD") then tl.fuel_type :: CHARACTER
 else 0
 END as product_code

But when I try it, I'm getting the below error:

Corresponding data types must be compatible in CASE expression or DECODE function. [SQL State=IX000, DB Errorcode=-800]

When I try this:

CASE
when l.src_country = 'USA' then tl.cat--prodUSA.description
when l.src_country = 'CAN' AND tl.fuel_type > 0 then tl.fuel_type :: CHAR
when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat in ("DEF","DEFD") then '4194304'
when l.src_country = 'CAN' and tl.fuel_type = 0 and tl.cat not in ("DEF","DEFD") then tl.fuel_type :: CHAR
else '0'
END as product_code

I'm getting the below error:

Converted value does not fit into the allotted space 

I need to cast the tl.fuel_type as a Character. What am I doing wrong here?


Solution

  • Suppose we have a one table setup like this:

    DROP TABLE IF EXISTS fuel_info;
    CREATE TEMP TABLE fuel_info
    (
        src_country    CHAR(3) NOT NULL,
        fuel_type      INTEGER NOT NULL,
        cat            CHAR(9) NOT NULL
    );
    
    INSERT INTO fuel_info VALUES('USA', 12, 'CAT1');
    INSERT INTO fuel_info VALUES('CAN', 10, 'ABC2');
    INSERT INTO fuel_info VALUES('CAN',  0, 'DEFD');
    INSERT INTO fuel_info VALUES('CAN',  0, 'WXYZ');
    INSERT INTO fuel_info VALUES('EUR',  1, 'P3X9');
    

    We can adapt the expressions in the question to reproduce the problem. For example:

    SELECT 
        CASE
        WHEN tl.src_country = 'USA' THEN tl.cat--prodUSA.description
        WHEN tl.src_country = 'CAN' AND tl.fuel_type > 0 THEN tl.fuel_type::CHAR
        WHEN tl.src_country = 'CAN' AND tl.fuel_type = 0 AND tl.cat IN ("DEF","DEFD") THEN '4194304'
        WHEN tl.src_country = 'CAN' AND tl.fuel_type = 0 AND tl.cat NOT IN ("DEF","DEFD") THEN tl.fuel_type::CHAR
        ELSE '0'
        END AS product_code
      FROM fuel_info AS tl;
    

    This generates the SQL -1207: Converted value does not fit into the allotted space error.

    You can fix it by specify big enough lengths for the CHAR type casts:

    SELECT 
        CASE
        WHEN tl.src_country = 'USA' THEN tl.cat--prodUSA.description
        WHEN tl.src_country = 'CAN' AND tl.fuel_type > 0 THEN tl.fuel_type::CHAR(7)
        WHEN tl.src_country = 'CAN' AND tl.fuel_type = 0 AND tl.cat IN ("DEF","DEFD") THEN '4194304'
        WHEN tl.src_country = 'CAN' AND tl.fuel_type = 0 AND tl.cat NOT IN ("DEF","DEFD") THEN tl.fuel_type::CHAR(7)
        ELSE '0'
        END AS product_code
      FROM fuel_info AS tl;
    

    This works, producing:

    CAT1
    10
    4194304
    0
    0