【问题标题】:Type casting in Netezza在 Netezza 中进行类型转换
【发布时间】:2015-07-31 15:46:19
【问题描述】:

基本上,我在源代码和 Target 都有 Netezza。在源代码中,每一列都定义为 NVARCHAR。

在通过 Informatica(ETL) 加载数据时,我们必须进行不同的类型转换,例如:

  • NVARCHAR -> 时间戳
  • NVARCHAR -> BYTEINT/SMALLINT/INT/BIGINT
  • NVARCHAR -> NUMERIC(18,0),NVARCHAR -> 浮点数

...等等。

我们不允许删除任何记录,因此如果任何转换失败,我们需要为该特定转换设置 NULL。 Informatica 中的一些可用功能无法推送到 Netezza,因为我们必须在 Informatica 中使用 PUSHDOWN 优化。所以我们试图在数据库中编写视图并在视图中执行所有类型转换。

当我们尝试使用 CASE 和 CAST 测试 NVARCHAR 值以查看它是否适合目标类型时,我们遇到了异常。

ERROR:  pg_atoi: error in "p": can't parse "p"

【问题讨论】:

  • 我已提议对您的问题进行编辑,以包括您在另一个问题中提到的特定测试用例。这需要一点时间才能显示出来。同时看看我的回答是否有帮助。
  • 对于“期待快速回复”,然后也没有回复有用的答案,我投了反对票,很遗憾。

标签: casting netezza


【解决方案1】:

这里有两个主要问题。

首先是找到一个函数,该函数将全面确定您的 NVARCHAR 列中的值是否真的代表一个数字。第二个是确保 CASE 语句的 THEN 元素在不需要时不会计算。

正如您所注意到的,内置的 TRANSLATE 功能可以做得不错,但它并非万无一失。据我所知,没有内置函数可以可靠地执行此检查。

但是,有两个包含的 UDF 可以很好地完成这项任务。这两个功能都必须由您的管理员明确启用。

  • isnumber ,包含在 INZA 函数中
  • regexp_like ,包含在 SQL 扩展工具包中

以下是同时使用这两种方法的示例,显示了对 SMALLINT 的强制转换。在每一个中,我都将测试 CASE 放在一个子选择中,以确保最终的 CAST 不会与原始值绝缘。您可能认为只能在两个嵌套的 CASE 中对此进行编码,但对于 UDF,您不能总是依赖这种行为。

isnumber 示例:

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 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2014-11-22
    相关资源
    最近更新 更多