Netezza的CASE声明

时间:2015-07-29 10:56:18

标签: casting case netezza

我是Netezza的新手,所以我可能无法弄清楚这个问题。

我有一个场景,在Neticzza作为数据库的信息中实现。由于信息无法提供/支持的功能很少,因此决定制作一些netezza视图并在信息中使用它们。

方案如下:

INDEX_BDV = Convert "SST_LDA_TEA2PLUSBUCKET.INDEX" from CHAR to SMALLINT
/!\ If conversion fails, do not reject the records but put a NULL as default value /!\

我正在尝试构建一个视图。我尝试构建测试查询以转换为smallint,如下所示:

SELECT CASE WHEN CAST('99999' AS NUMERIC(18,0)) >= -32678 AND
                 CAST('99999' AS NUMERIC(18,0)) <= 32767
            THEN CAST('99999' AS smallint)
            ELSE NULL END

但每次失败时都会出现如下错误信息:

*ERROR [HY000] ERROR:  pg_atoi: error reading "99999": Numerical result out of range */

我尝试了其他替代方案,如下所示:

SELECT CASE WHEN CAST('99999' AS NUMERIC(18,0)) >= -32678 AND
                 CAST('99999' AS NUMERIC(18,0)) <= 32767
            THEN 'A'
            ELSE NULL END

结果为NULL。但对于上述情况,它不会返回NULL,而是返回异常。

2 个答案:

答案 0 :(得分:0)

您的查询工作正常,问题不在查询中。告诉我们另一个代码。您可以使用更简单的查询形式。

SELECT CASE WHEN CAST('99999' AS NUMERIC(18,0)) between -32678 AND 32767
            THEN CAST('99999' AS smallint)
            ELSE NULL 
       END

答案 1 :(得分:0)

您的第一个查询失败,因为系统不能作为SMALLINT CAST 99999,它只涵盖32767的范围-32678。文字的CAST将在编译时进行评估,永远不会成功运行时以评估CASE逻辑。这可能让你感到困惑。

SELECT CASE WHEN CAST('99999' AS NUMERIC(18,0)) >= -32678 AND
                 CAST('99999' AS NUMERIC(18,0)) <= 32767
            THEN CAST('99999' AS smallint)
            ELSE NULL END

如果您针对实际表中的数据进行测试,它将按预期执行。

TESTDB.ADMIN(ADMIN)=> create table smallint_test (col1 varchar(10));
CREATE TABLE
TESTDB.ADMIN(ADMIN)=> insert into smallint_test values ('99999');
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> insert into smallint_test values ('1');
INSERT 0 1
TESTDB.ADMIN(ADMIN)=> SELECT COL1,
   CASE
      WHEN CAST(COL1 AS NUMERIC(18,0)) >= -32678
      AND CAST(COL1 AS  NUMERIC(18,0)) <= 32767
      THEN CAST(COL1 AS SMALLINT)
      ELSE NULL
   END
FROM SMALLINT_TEST;

 COL1  | CASE
-------+------
 1     |    1
 99999 |
(2 rows)

根据您的其他评论,我认为来自@Niederee to this question的答案可以帮助您。

使用他描述的TRANSLATE函数,你可以这样做:

SELECT INDEX,
   CASE
      WHEN
         TRANSLATE(INDEX,'0123456789','') IN ('','.','-','-.')
      THEN
         CASE
            WHEN INDEX BETWEEN -32678 AND 32767
            THEN INDEX::SMALLINT
            ELSE NULL
         END
      ELSE NULL
   END THE_NUMBER
FROM TPB;

 INDEX | THE_NUMBER
-------+------------
 1     |          1
 99999 |
 p     |
 p99   |
(4 rows)