基本上,我在源头和目标上都有Netezza。在源中,每列都定义为NVARCHAR。
通过Informatica(ETL)加载数据时,我们必须进行不同类型的转换,例如:
......等等。
我们不允许删除任何记录,因此如果任何转换失败,我们需要为该特定转换设置NULL。 Informatica中很少有功能无法推送到Netezza,因为我们必须在Informatica中使用PUSHDOWN优化。因此,我们尝试在数据库中编写视图并在视图中执行所有类型转换。
当我们尝试使用CASE和CAST测试NVARCHAR值以查看它是否适合目标类型时,我们遇到异常困难。
ERROR: pg_atoi: error in "p": can't parse "p"
答案 0 :(得分:1)
这里有两个主要问题。
首先是找到一个能够全面确定NVARCHAR列中的值是否实际代表数字的函数。第二个是确保CASE声明的THEN元素在不需要的时候进行评估。
正如您所注意到的,内置的TRANSLATE功能可以做得不错,但它不是万无一失的。据我所知,没有内置功能可以可靠地执行此检查。
但是,有两个包含UDF可以很好地完成此任务。管理员必须明确启用这两项功能。
以下是使用两者的示例,显示了对SMALLINT的强制转换。在每一个中,我将测试CASE放在子选择中,以确保最终的CAST不与原始值隔离。您可能认为只能在两个嵌套的CASE中对此进行编码,但使用UDF时,您始终无法依赖该行为。
是数量样本:
SELECT ORIG_COL,
CASE
WHEN COL1 BETWEEN -32678 AND 32767
THEN COL1::SMALLINT
ELSE NULL
END THE_NUMBER
FROM (
SELECT
COL1 ORIG_COL,
CASE
WHEN isnumber(COL1)
THEN COL1
ELSE NULL
END COL1
FROM test_cast
)
t1;
ORIG_COL | THE_NUMBER
----------+------------
NAN |
1 | 1
-+9,9.09 |
99999 |
(4 rows)
regexp_like示例,使用@Niederee在回答this question时提供的模式。
SELECT ORIG_COL,
CASE
WHEN COL1 BETWEEN -32678 AND 32767
THEN COL1::SMALLINT
ELSE NULL
END THE_NUMBER
FROM (
SELECT COL1 ORIG_COL,
CASE
WHEN REGEXP_LIKE(COL1, '^[+-]?[0-9]*[.]?[0-9]*$')
THEN COL1
ELSE NULL
END COL1
FROM test_cast
)
t1;
ORIG_COL | THE_NUMBER
----------+------------
99999 |
NAN |
1 | 1
-+9,9.09 |
(4 rows)
请注意,您需要管理员才能使用这些功能。
isnumber函数来自INZA安装,如果INZA就位,可以这样加载:
[nz@netezza ~]$ cd /nz/extensions/nz/nzlua/examples/
[nz@netezza examples]$ ../bin/nzl -d testdb isnumber.nzl
Compiling: isnumber.nzl
####################################################################
UdxName = isnumber
UdxType = UDF
Arguments = VARCHAR(ANY)
Result = BOOL
Dependencies = INZA.INZA.LIBNZLUA_3_2_0
NZUDXCOMPILE OPTIONS: (--replbyval --nullcall --unfenced --mem 2m)
CREATE FUNCTION
[nz@netezza examples]$
SQL扩展工具包的安装过程已经很好地记录了,并且包含了regexp_like函数。