How do I cast a string to integer and have 0 in case of error in the cast with PostgreSQL?

前端 未结 13 903
误落风尘
误落风尘 2020-12-02 06:27

In PostgreSQL I have a table with a varchar column. The data is supposed to be integers and I need it in integer type in a query. Some values are empty strings. The followin

相关标签:
13条回答
  • 2020-12-02 06:44

    The following function does

    • use a default value (error_result) for not castable results e.g abc or 999999999999999999999999999999999999999999
    • keeps null as null
    • trims away spaces and other whitespace in input
    • values casted as valid bigints are compared against lower_bound to e.g enforce positive values only
    CREATE OR REPLACE FUNCTION cast_to_bigint(text) 
    RETURNS BIGINT AS $$
    DECLARE big_int_value BIGINT DEFAULT NULL;
    DECLARE error_result  BIGINT DEFAULT -1;
    DECLARE lower_bound   BIGINT DEFAULT 0;
    BEGIN
        BEGIN
            big_int_value := CASE WHEN $1 IS NOT NULL THEN GREATEST(TRIM($1)::BIGINT, lower_bound) END;
        EXCEPTION WHEN OTHERS THEN
            big_int_value := error_result;
        END;
    RETURN big_int_value;
    END;
    
    0 讨论(0)
  • 2020-12-02 06:50

    This might be somewhat of a hack, but it got the job done in our case:

    (0 || myfield)::integer
    

    Explanation (Tested on Postgres 8.4):

    The above mentioned expression yields NULL for NULL-values in myfield and 0 for empty strings (This exact behaviour may or may not fit your use case).

    SELECT id, (0 || values)::integer from test_table ORDER BY id
    

    Test data:

    CREATE TABLE test_table
    (
      id integer NOT NULL,
      description character varying,
      "values" character varying,
      CONSTRAINT id PRIMARY KEY (id)
    )
    
    -- Insert Test Data
    INSERT INTO test_table VALUES (1, 'null', NULL);
    INSERT INTO test_table VALUES (2, 'empty string', '');
    INSERT INTO test_table VALUES (3, 'one', '1');
    

    The query will yield the following result:

     ---------------------
     |1|null        |NULL|
     |2|empty string|0   |
     |3|one         |1   |
     ---------------------
    

    Whereas select only values::integer will result in an error message.

    Hope this helps.

    0 讨论(0)
  • 2020-12-02 06:51
    CREATE OR REPLACE FUNCTION parse_int(s TEXT) RETURNS INT AS $$
    BEGIN
      RETURN regexp_replace(('0' || s), '[^\d]', '', 'g')::INT;
    END;
    $$ LANGUAGE plpgsql;
    

    This function will always return 0 if there are no digits in the input string.

    SELECT parse_int('test12_3test');

    will return 123

    0 讨论(0)
  • 2020-12-02 06:53

    You could also create your own conversion function, inside which you can use exception blocks:

    CREATE OR REPLACE FUNCTION convert_to_integer(v_input text)
    RETURNS INTEGER AS $$
    DECLARE v_int_value INTEGER DEFAULT NULL;
    BEGIN
        BEGIN
            v_int_value := v_input::INTEGER;
        EXCEPTION WHEN OTHERS THEN
            RAISE NOTICE 'Invalid integer value: "%".  Returning NULL.', v_input;
            RETURN NULL;
        END;
    RETURN v_int_value;
    END;
    $$ LANGUAGE plpgsql;
    

    Testing:

    =# select convert_to_integer('1234');
     convert_to_integer 
    --------------------
                   1234
    (1 row)
    
    =# select convert_to_integer('');
    NOTICE:  Invalid integer value: "".  Returning NULL.
     convert_to_integer 
    --------------------
    
    (1 row)
    
    =# select convert_to_integer('chicken');
    NOTICE:  Invalid integer value: "chicken".  Returning NULL.
     convert_to_integer 
    --------------------
    
    (1 row)
    
    0 讨论(0)
  • 2020-12-02 06:53

    SUBSTRING may help for some cases, you can limit the size of the int.

    SELECT CAST(SUBSTRING('X12312333333333', '([\d]{1,9})') AS integer);
    
    0 讨论(0)
  • 2020-12-02 06:59

    I also have the same need but that works with JPA 2.0 and Hibernate 5.0.2:

    SELECT p FROM MatchProfile p WHERE CONCAT(p.id, '') = :keyword
    

    Works wonders. I think it works with LIKE too.

    0 讨论(0)
提交回复
热议问题