我是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,而是返回异常。
答案 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)